libimg/src/rotate-ip.c

91 lines
2.0 KiB
C

#include <libimg.h>
static void img_rotate_ip90(img_t img)
{
if(img.width != img.height) return;
img_pixel_t *tl = img.pixels;
img_pixel_t *tr = img.pixels + img.width - 1;
img_pixel_t *bl = tl + (img.height - 1) * img.stride;
img_pixel_t *br = tr + (img.height - 1) * img.stride;
for(int y=0; y < img.height >> 1; y++)
{
for(int x=y, dx=0, dy=0; x < img.width-1 - y; x++, dx++,
dy+=img.stride)
{
int swp = tl[dx];
tl[dx] = bl[-dy];
bl[-dy] = br[-dx];
br[-dx] = tr[dy];
tr[dy] = swp;
}
tl += img.stride + 1;
tr += img.stride - 1;
bl -= img.stride - 1;
br -= img.stride + 1;
}
}
static void img_rotate_ip180(img_t img)
{
img_pixel_t *tl = img.pixels;
img_pixel_t *br = tl + (img.height - 1) * img.stride + img.width - 1;
for(int y = 0; y < (img.height+1) >> 1; y++)
{
/* If both pointers reach the same line (height is odd), we
must stop at half of the width */
int limit = img.width;
if(tl+img.stride-1 == br) limit >>= 1;
for(int x = 0; x < limit; x++)
{
int swp = tl[x];
tl[x] = br[-x];
br[-x] = swp;
}
tl += img.stride;
br -= img.stride;
}
}
static void img_rotate_ip270(img_t img)
{
/* Same as img_rotate_ip90, except for the order of assignments */
if(img.width != img.height) return;
img_pixel_t *tl = img.pixels;
img_pixel_t *tr = img.pixels + img.width - 1;
img_pixel_t *bl = tl + (img.height - 1) * img.stride;
img_pixel_t *br = tr + (img.height - 1) * img.stride;
for(int y=0; y < img.height >> 1; y++)
{
for(int x=y, dx=0, dy=0; x < img.width-1 - y; x++, dx++,
dy+=img.stride)
{
/* Only difference with img_rotate_ip90 */
int swp = tl[dx];
tl[dx] = tr[dy];
tr[dy] = br[-dx];
br[-dx] = bl[-dy];
bl[-dy] = swp;
}
tl += img.stride + 1;
tr += img.stride - 1;
bl -= img.stride - 1;
br -= img.stride + 1;
}
}
void img_rotate_inplace(img_t img, int angle)
{
if(angle == 90) img_rotate_ip90(img);
if(angle == 180) img_rotate_ip180(img);
if(angle == 270) img_rotate_ip270(img);
}