[gthumb: 104/129] rotate tool: implemented skew algorithm, with linear interpolation
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 104/129] rotate tool: implemented skew algorithm, with linear interpolation
- Date: Wed, 27 Apr 2011 20:59:07 +0000 (UTC)
commit 7924e1e91851979678315d5adf7591d32dee74d2
Author: Stefano Pettini <spettini users sourceforge net>
Date: Thu Apr 21 11:53:06 2011 +0100
rotate tool: implemented skew algorithm, with linear interpolation
extensions/file_tools/gdk-pixbuf-rotate.c | 146 +++++++++++++++++++++++------
1 files changed, 117 insertions(+), 29 deletions(-)
---
diff --git a/extensions/file_tools/gdk-pixbuf-rotate.c b/extensions/file_tools/gdk-pixbuf-rotate.c
index 96fb73c..24a6f9e 100644
--- a/extensions/file_tools/gdk-pixbuf-rotate.c
+++ b/extensions/file_tools/gdk-pixbuf-rotate.c
@@ -19,33 +19,128 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <math.h>
#include <gthumb.h>
#include "gdk-pixbuf-rotate.h"
-GdkPixbuf*
-_gdk_pixbuf_rotate_crop (GdkPixbuf *src_pixbuf,
- int center_x,
- int center_y,
- double angle)
+#define interpolate_value(v1, f1, v2, f2) (CLAMP ((f1) * (v1) + (f2) * (v2), 0, 255))
+
+
+static GdkPixbuf*
+skew(GdkPixbuf *src_pixbuf,
+ double angle,
+ gint auto_crop)
{
- // TODO: implement the algorithm
+ GdkPixbuf *new_pixbuf;
+ double skew;
+ int src_rowstride, new_rowstride, n_channels;
+ int width;
+ int width_new;
+ int height;
+ int delta_max;
+ int x;
+ int y;
+ guchar *p_src, *p_src2;
+ guchar *p_new, *p_new_row;
+ guchar r1, g1, b1;
+ guchar r2, g2, b2;
+ double delta;
+ double f1, f2;
+ int x1, x2;
- g_object_ref (src_pixbuf);
- return src_pixbuf;
-}
+ if (angle != 0.0 && angle >= -45 && angle <= 45.0) {
+ skew = tan (angle / 180.0 * 3.1415926535);
-GdkPixbuf*
-_gdk_pixbuf_rotate_no_crop (GdkPixbuf *src_pixbuf,
- int center_x,
- int center_y,
- double angle)
-{
- // TODO: implement the algorithm
+ n_channels = gdk_pixbuf_get_n_channels (src_pixbuf);
+
+ width = gdk_pixbuf_get_width (src_pixbuf);
+ height = gdk_pixbuf_get_height (src_pixbuf);
+ delta_max = (int) floor (fabs (skew * height));
+
+ if (auto_crop)
+ width_new = width - delta_max;
+ else
+ width_new = width + delta_max;
+
+ new_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src_pixbuf),
+ gdk_pixbuf_get_has_alpha (src_pixbuf),
+ gdk_pixbuf_get_bits_per_sample (src_pixbuf),
+ width_new,
+ height);
+
+ p_src = gdk_pixbuf_get_pixels (src_pixbuf);
+ p_new = gdk_pixbuf_get_pixels (new_pixbuf);
+
+ src_rowstride = gdk_pixbuf_get_rowstride (src_pixbuf);
+ new_rowstride = gdk_pixbuf_get_rowstride (new_pixbuf);
+
+ for (y = 0; y < height; y++) {
+
+ if (skew > 0)
+ delta = skew * y;
+ else
+ delta = skew * -(height - y - 1);
+
+ f1 = delta - floor (delta);
+ f2 = 1.0 - f1;
+
+ p_new_row = p_new;
+
+ for (x = 0; x < width_new; x++) {
+
+ x1 = (int) floor (x - delta);
+ x2 = (int) ceil (x - delta);
+
+ if (auto_crop) {
+ x1 += delta_max;
+ x2 += delta_max;
+ }
+
+ if (x1 < 0 || x1 >= width) {
+ r1 = 0;
+ g1 = 0;
+ b1 = 0;
+ }
+ else {
+ p_src2 = p_src + x1 * n_channels;
+
+ r1 = p_src2[RED_PIX];
+ g1 = p_src2[GREEN_PIX];
+ b1 = p_src2[BLUE_PIX];
+ }
+
+ if (x2 < 0 || x2 >= width) {
+ r2 = 0;
+ g2 = 0;
+ b2 = 0;
+ }
+ else {
+ p_src2 = p_src + x2 * n_channels;
+
+ r2 = p_src2[RED_PIX];
+ g2 = p_src2[GREEN_PIX];
+ b2 = p_src2[BLUE_PIX];
+ }
+
+ p_new_row[RED_PIX] = interpolate_value(r1, f1, r2, f2);
+ p_new_row[GREEN_PIX] = interpolate_value(g1, f1, g2, f2);
+ p_new_row[BLUE_PIX] = interpolate_value(b1, f1, b2, f2);
+
+ p_new_row += n_channels;
+ }
+
+ p_src += src_rowstride;
+ p_new += new_rowstride;
+ }
+ }
+ else {
+ g_object_ref (src_pixbuf);
+ new_pixbuf = src_pixbuf;
+ }
- g_object_ref (src_pixbuf);
- return src_pixbuf;
+ return new_pixbuf;
}
@@ -57,17 +152,10 @@ _gdk_pixbuf_rotate (GdkPixbuf *src_pixbuf,
gint auto_crop)
{
GdkPixbuf *new_pixbuf;
-
- if (angle == 0.0) {
- new_pixbuf = src_pixbuf;
- g_object_ref (new_pixbuf);
- }
- else if (auto_crop) {
- new_pixbuf = _gdk_pixbuf_rotate_crop (src_pixbuf, center_x, center_y, angle);
- }
- else {
- new_pixbuf = _gdk_pixbuf_rotate_no_crop (src_pixbuf, center_x, center_y, angle);
- }
+
+ // TODO: implement the correct rotate algorithm
+
+ new_pixbuf = skew (src_pixbuf, angle, auto_crop);
return new_pixbuf;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]