mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-18 20:10:29 +01:00
wrlib: move fixed angle rotation code to dedicated functions
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 <christophe.curis@free.fr>
This commit is contained in:
committed by
Carlos R. Mafra
parent
be5d04525d
commit
f85066a19e
@@ -35,6 +35,7 @@ libwraster_la_SOURCES = \
|
|||||||
scale.c \
|
scale.c \
|
||||||
scale.h \
|
scale.h \
|
||||||
rotate.c \
|
rotate.c \
|
||||||
|
rotate.h \
|
||||||
flip.c \
|
flip.c \
|
||||||
convolve.c \
|
convolve.c \
|
||||||
save_xpm.c \
|
save_xpm.c \
|
||||||
|
|||||||
267
wrlib/rotate.c
267
wrlib/rotate.c
@@ -25,8 +25,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include "wraster.h"
|
#include "wraster.h"
|
||||||
|
#include "rotate.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -34,15 +37,13 @@
|
|||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846
|
||||||
#endif
|
#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 *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
|
* Angle steps below this value would represent a rotation
|
||||||
* of less than 1 pixel for a 4k wide image, so not worth
|
* 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) &&
|
} else if ((angle > 90.0 - min_usable_angle) &&
|
||||||
(angle < 90.0 + min_usable_angle)) {
|
(angle < 90.0 + min_usable_angle)) {
|
||||||
nwidth = image->height;
|
return rotate_image_90(image);
|
||||||
nheight = image->width;
|
|
||||||
|
|
||||||
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) &&
|
} else if ((angle > 180.0 - min_usable_angle) &&
|
||||||
(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) &&
|
} else if ((angle > 270.0 - min_usable_angle) &&
|
||||||
(angle < 270.0 + min_usable_angle)) {
|
(angle < 270.0 + min_usable_angle)) {
|
||||||
nwidth = image->height;
|
return rotate_image_270(image);
|
||||||
nheight = image->width;
|
|
||||||
|
|
||||||
img = RCreateImage(nwidth, nheight, True);
|
} else {
|
||||||
if (!img)
|
return rotate_image_any(image, angle);
|
||||||
return NULL;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bpp == 3) {
|
static RImage *rotate_image_90(RImage *source)
|
||||||
unsigned char *optr, *nptr;
|
{
|
||||||
|
RImage *target;
|
||||||
|
int nwidth, nheight;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
optr = image->data;
|
nwidth = source->height;
|
||||||
|
nheight = source->width;
|
||||||
|
|
||||||
for (x = nwidth; x; x--) {
|
target = RCreateImage(nwidth, nheight, (source->format != RRGBFormat));
|
||||||
nptr = img->data + 4 * nwidth * nheight - x * 4;
|
if (!target)
|
||||||
for (y = nheight; y; y--) {
|
return NULL;
|
||||||
nptr[0] = *optr++;
|
|
||||||
nptr[1] = *optr++;
|
|
||||||
nptr[2] = *optr++;
|
|
||||||
nptr[3] = 255;
|
|
||||||
|
|
||||||
nptr -= 4 * nwidth;
|
if (source->format == RRGBFormat) {
|
||||||
}
|
unsigned char *optr, *nptr;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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 += 3 * nwidth;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} 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
|
#endif
|
||||||
|
|
||||||
static RImage *rotateImage(RImage *image, float angle)
|
static RImage *rotate_image_any(RImage *source, float angle)
|
||||||
{
|
{
|
||||||
(void) angle;
|
(void) angle;
|
||||||
puts("NOT FULLY IMPLEMENTED");
|
puts("NOT FULLY IMPLEMENTED");
|
||||||
return RCloneImage(image);
|
return RCloneImage(source);
|
||||||
#if 0
|
#if 0
|
||||||
RImage *img;
|
RImage *img;
|
||||||
int nwidth, nheight;
|
int nwidth, nheight;
|
||||||
|
|||||||
30
wrlib/rotate.h
Normal file
30
wrlib/rotate.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user