[gthumb] cairo-scale: removed the need for a vertical_scale function
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] cairo-scale: removed the need for a vertical_scale function
- Date: Sun, 19 Aug 2012 08:37:15 +0000 (UTC)
commit 5a494668070e9733ac5df59e2482246fe3b72a60
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri Aug 17 12:13:27 2012 +0200
cairo-scale: removed the need for a vertical_scale function
use an horizonal scale + transpose twice instead of an horizontal + vertical
scale, this will allow to simplify speed optimization.
extensions/file_tools/cairo-scale.c | 142 +++++------------------------------
1 files changed, 18 insertions(+), 124 deletions(-)
---
diff --git a/extensions/file_tools/cairo-scale.c b/extensions/file_tools/cairo-scale.c
index d3c4bc7..728a660 100644
--- a/extensions/file_tools/cairo-scale.c
+++ b/extensions/file_tools/cairo-scale.c
@@ -112,7 +112,6 @@ _cairo_image_surface_scale_nearest (cairo_surface_t *image,
/* -- _cairo_image_surface_scale_filter -- */
-#define WORKLOAD_FACTOR 0.265
#define EPSILON ((double) 1.0e-16)
@@ -232,104 +231,10 @@ clamp_pixel (double v)
static void
-horizontal_scale (resize_filter_t *resize_filter,
- cairo_surface_t *image,
- cairo_surface_t *scaled,
- double x_factor)
-{
- double scale;
- double support;
- int x;
- guchar *p_src;
- guchar *p_dest;
- int src_rowstride;
- int dest_rowstride;
- double *weights;
- guchar *p_src_row;
- guchar *p_dest_pixel;
-
- cairo_surface_flush (scaled);
-
- scale = MAX (1.0 / x_factor + EPSILON, 1.0);
- support = scale * resize_filter_get_support (resize_filter);
- if (support < 0.5) {
- support = 0.5;
- scale = 1.0;
- }
-
- p_src = cairo_image_surface_get_data (image);
- p_dest = cairo_image_surface_get_data (scaled);
- src_rowstride = cairo_image_surface_get_stride (image);
- dest_rowstride = cairo_image_surface_get_stride (scaled);
- weights = g_new (double, 2.0 * support + 3.0);
-
- scale = reciprocal (scale);
- for (x = 0; x < cairo_image_surface_get_width (scaled); x++) {
- double bisect;
- int start;
- int stop;
- double density;
- int n;
- int y;
-
- bisect = (x + 0.5) / x_factor + EPSILON;
- start = MAX (bisect - support + 0.5, 0.0);
- stop = MIN (bisect + support + 0.5, cairo_image_surface_get_width (image));
- density = 0.0;
-
- for (n = 0; n < stop - start; n++) {
- weights[n] = resize_filter_get_weight (resize_filter, scale * ((double) (start + n) - bisect + 0.5));
- density += weights[n];
- }
-
- if ((density != 0.0) && (density != 1.0)) {
- register int i;
-
- density = reciprocal (density);
- for (i = 0; i < n; i++)
- weights[i] *= density;
- }
-
- p_src_row = p_src;
- p_dest_pixel = p_dest + (x * 4);
- for (y = 0; y < cairo_image_surface_get_height (scaled); y++) {
- guchar *p_src_pixel;
- double r, g, b, a;
- register int i;
-
- p_src_pixel = p_src_row + (start * 4);
- r = g = b = a = 0.0;
- for (i = 0; i < n; i++) {
- double w = weights[i];
- r += w * p_src_pixel[CAIRO_RED];
- g += w * p_src_pixel[CAIRO_GREEN];
- b += w * p_src_pixel[CAIRO_BLUE];
- a += w * p_src_pixel[CAIRO_ALPHA];
-
- p_src_pixel += 4;
- }
-
- p_dest_pixel[CAIRO_RED] = clamp_pixel (r);
- p_dest_pixel[CAIRO_GREEN] = clamp_pixel (g);
- p_dest_pixel[CAIRO_BLUE] = clamp_pixel (b);
- p_dest_pixel[CAIRO_ALPHA] = clamp_pixel (a);
-
- p_dest_pixel += dest_rowstride;
- p_src_row += src_rowstride;
- }
- }
-
- cairo_surface_mark_dirty (scaled);
-
- g_free (weights);
-}
-
-
-static void
-vertical_scale (resize_filter_t *resize_filter,
- cairo_surface_t *image,
- cairo_surface_t *scaled,
- double y_factor)
+horizontal_scale_transpose (resize_filter_t *resize_filter,
+ cairo_surface_t *image,
+ cairo_surface_t *scaled,
+ double scale_factor)
{
double scale;
double support;
@@ -339,12 +244,12 @@ vertical_scale (resize_filter_t *resize_filter,
int src_rowstride;
int dest_rowstride;
double *weights;
- guchar *p_src_col;
+ guchar *p_src_row;
guchar *p_dest_pixel;
cairo_surface_flush (scaled);
- scale = MAX (1.0 / y_factor + EPSILON, 1.0);
+ scale = MAX (1.0 / scale_factor + EPSILON, 1.0);
support = scale * resize_filter_get_support (resize_filter);
if (support < 0.5) {
support = 0.5;
@@ -366,9 +271,9 @@ vertical_scale (resize_filter_t *resize_filter,
int n;
int x;
- bisect = (y + 0.5) / y_factor + EPSILON;
+ bisect = (y + 0.5) / scale_factor + EPSILON;
start = MAX (bisect - support + 0.5, 0.0);
- stop = MIN (bisect + support + 0.5, cairo_image_surface_get_height (image));
+ stop = MIN (bisect + support + 0.5, cairo_image_surface_get_width (image));
density = 0.0;
for (n = 0; n < stop - start; n++) {
@@ -384,14 +289,14 @@ vertical_scale (resize_filter_t *resize_filter,
weights[i] *= density;
}
- p_src_col = p_src + (start * src_rowstride);
+ p_src_row = p_src;
p_dest_pixel = p_dest + (y * dest_rowstride);
for (x = 0; x < cairo_image_surface_get_width (scaled); x++) {
guchar *p_src_pixel;
double r, g, b, a;
register int i;
- p_src_pixel = p_src_col;
+ p_src_pixel = p_src_row + (start * 4);
r = g = b = a = 0.0;
for (i = 0; i < n; i++) {
double w = weights[i];
@@ -400,7 +305,7 @@ vertical_scale (resize_filter_t *resize_filter,
b += w * p_src_pixel[CAIRO_BLUE];
a += w * p_src_pixel[CAIRO_ALPHA];
- p_src_pixel += src_rowstride;
+ p_src_pixel += 4;
}
p_dest_pixel[CAIRO_RED] = clamp_pixel (r);
@@ -409,7 +314,7 @@ vertical_scale (resize_filter_t *resize_filter,
p_dest_pixel[CAIRO_ALPHA] = clamp_pixel (a);
p_dest_pixel += 4;
- p_src_col += 4;
+ p_src_row += src_rowstride;
}
}
@@ -449,23 +354,12 @@ _cairo_image_surface_scale_filter (cairo_surface_t *image,
resize_filter = resize_filter_create (filter);
x_factor = (double) new_width / src_width;
y_factor = (double) new_height / src_height;
- if (x_factor * y_factor > WORKLOAD_FACTOR) {
- tmp = cairo_surface_create_similar_image (image,
- CAIRO_FORMAT_ARGB32,
- new_width,
- src_height);
-
- horizontal_scale (resize_filter, image, tmp, x_factor);
- vertical_scale (resize_filter, tmp, scaled, y_factor);
- }
- else {
- tmp = cairo_surface_create_similar_image (image,
- CAIRO_FORMAT_ARGB32,
- src_width,
- new_height);
- vertical_scale (resize_filter, image, tmp, y_factor);
- horizontal_scale (resize_filter, tmp, scaled, x_factor);
- }
+ tmp = cairo_surface_create_similar_image (image,
+ CAIRO_FORMAT_ARGB32,
+ src_height,
+ new_width);
+ horizontal_scale_transpose (resize_filter, image, tmp, x_factor);
+ horizontal_scale_transpose (resize_filter, tmp, scaled, y_factor);
resize_filter_destroy (resize_filter);
cairo_surface_destroy (tmp);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]