mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
137 lines
4.3 KiB
C++
137 lines
4.3 KiB
C++
//+----------------------------------------------------------------------------+
|
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
|
//| Copyright: (C) 2001 - 2017 Twan van Laarhoven and Sean Hunt |
|
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
|
//+----------------------------------------------------------------------------+
|
|
|
|
// ----------------------------------------------------------------------------- : Includes
|
|
|
|
#include <util/prec.hpp>
|
|
#include <gfx/gfx.hpp>
|
|
|
|
// ----------------------------------------------------------------------------- : Implementation
|
|
|
|
// Rotates an image
|
|
// 'Rotater' is a function object that knows how to 'rotate' a pixel coordinate
|
|
template <class Rotater>
|
|
Image rotate_image_impl(Image img) {
|
|
UInt width = img.GetWidth(), height = img.GetHeight();
|
|
// initialize the return image
|
|
Image ret;
|
|
Rotater::init(ret, width, height);
|
|
Byte* in = img.GetData(), *out = ret.GetData();
|
|
// rotate each pixel
|
|
for (UInt y = 0 ; y < height ; ++y) {
|
|
for (UInt x = 0 ; x < width ; ++x) {
|
|
memcpy(out + 3 * Rotater::offset(x, y, width, height), in, 3);
|
|
in += 3;
|
|
}
|
|
}
|
|
// don't forget alpha
|
|
if (img.HasAlpha()) {
|
|
ret.InitAlpha();
|
|
in = img.GetAlpha();
|
|
out = ret.GetAlpha();
|
|
for (UInt y = 0 ; y < height ; ++y) {
|
|
for (UInt x = 0 ; x < width ; ++x) {
|
|
out[Rotater::offset(x, y, width, height)] = *in;
|
|
in += 1;
|
|
}
|
|
}
|
|
}
|
|
// ret is rotated image
|
|
return ret;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------- : Rotations
|
|
|
|
// Function object to handle rotation
|
|
struct Rotate90deg {
|
|
/// Init a rotated image, where the source is w * h pixels
|
|
inline static void init(Image& img, UInt w, UInt h) {
|
|
img.Create(h, w, false);
|
|
}
|
|
/// Offset in the target data, x, y, w, h are SOURCE coordintes
|
|
inline static int offset(UInt x, UInt y, UInt w, UInt h) {
|
|
int mx = y;
|
|
int my = w - x - 1;
|
|
return h * my + mx; // note: h, since that is the width of the target image
|
|
}
|
|
};
|
|
|
|
struct Rotate180deg {
|
|
inline static void init(Image& img, UInt w, UInt h) {
|
|
img.Create(w, h, false);
|
|
}
|
|
inline static int offset(UInt x, UInt y, UInt w, UInt h) {
|
|
UInt mx = w - x - 1;
|
|
UInt my = h - y - 1;
|
|
return w * my + mx;
|
|
}
|
|
};
|
|
|
|
struct Rotate270deg {
|
|
inline static void init(Image& img, UInt w, UInt h) {
|
|
img.Create(h, w, false);
|
|
}
|
|
inline static int offset(UInt x, UInt y, UInt w, UInt h) {
|
|
UInt mx = h - y - 1;
|
|
UInt my = x;
|
|
return h * my + mx;
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------- : Interface
|
|
|
|
Image rotate_image(const Image& image, Radians angle) {
|
|
double a = constrain_radians(angle);
|
|
if (is_rad0(a)) return image;
|
|
if (is_rad90(a)) return rotate_image_impl<Rotate90deg> (image);
|
|
if (is_rad180(a)) return rotate_image_impl<Rotate180deg>(image);
|
|
if (is_rad270(a)) return rotate_image_impl<Rotate270deg>(image);
|
|
else {
|
|
if (!image.HasAlpha()) const_cast<Image&>(image).InitAlpha();
|
|
return image.Rotate(angle, wxPoint(0,0));
|
|
}
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------- : Flipping images
|
|
|
|
// reverse a list of n chunks of size 'step'
|
|
void do_flip(Byte const* in, Byte* out, int step, int n) {
|
|
for (int i = 0, j = n-1 ; i < n ; ++i, --j) {
|
|
memcpy(&out[i*step], &in[j*step], step);
|
|
}
|
|
}
|
|
void do_flip(Byte const* in, Byte* out, int step1, int n1, int n2) {
|
|
int step2 = step1 * n1;
|
|
for (int i = 0 ; i < n2 ; ++i) {
|
|
do_flip(in,out,step1,n1);
|
|
in += step2;
|
|
out += step2;
|
|
}
|
|
}
|
|
|
|
Image flip_image_horizontal(Image const& img) {
|
|
int w = img.GetWidth(), h= img.GetHeight();
|
|
Image out(w,h,false);
|
|
do_flip(img.GetData(), out.GetData(), 3, w, h);
|
|
if (img.HasAlpha()) {
|
|
out.InitAlpha();
|
|
do_flip(img.GetAlpha(), out.GetAlpha(), 1, w, h);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
Image flip_image_vertical(Image const& img) {
|
|
int w = img.GetWidth(), h= img.GetHeight();
|
|
Image out(w,h,false);
|
|
do_flip(img.GetData(), out.GetData(), 3 * w, h);
|
|
if (img.HasAlpha()) {
|
|
out.InitAlpha();
|
|
do_flip(img.GetAlpha(), out.GetAlpha(), 1 * w, h);
|
|
}
|
|
return out;
|
|
}
|