[gimp] app: parallelize gimpbrush-transform.cc
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: parallelize gimpbrush-transform.cc
- Date: Wed, 4 Apr 2018 21:54:03 +0000 (UTC)
commit c8d4c079a204dded5429f336e394e492a581226a
Author: Ell <ell_se yahoo com>
Date: Wed Apr 4 16:57:35 2018 -0400
app: parallelize gimpbrush-transform.cc
Use gimp_parallel_distribute_foo() to parallelize the brush
transform functions.
app/core/gimpbrush-transform.cc | 683 +++++++++++++++++++++------------------
1 files changed, 365 insertions(+), 318 deletions(-)
---
diff --git a/app/core/gimpbrush-transform.cc b/app/core/gimpbrush-transform.cc
index 5fcdf26..fc83488 100644
--- a/app/core/gimpbrush-transform.cc
+++ b/app/core/gimpbrush-transform.cc
@@ -33,11 +33,16 @@ extern "C"
#include "gegl/gimp-gegl-loops.h"
+#include "gimp-parallel.h"
#include "gimpbrush.h"
#include "gimpbrush-transform.h"
#include "gimptempbuf.h"
+#define MIN_PARALLEL_SUB_SIZE 64
+#define MIN_PARALLEL_SUB_AREA (MIN_PARALLEL_SUB_SIZE * MIN_PARALLEL_SUB_SIZE)
+
+
/* local function prototypes */
static void gimp_brush_transform_bounding_box (GimpBrush *brush,
@@ -115,7 +120,6 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
{
GimpTempBuf *result;
GimpTempBuf *source;
- guchar *dest;
const guchar *src;
GimpMatrix3 matrix;
gint src_width;
@@ -136,18 +140,6 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
gint src_walk_uy_i;
gint src_walk_vx_i;
gint src_walk_vy_i;
- gint src_space_cur_pos_x;
- gint src_space_cur_pos_y;
- gint src_space_cur_pos_x_i;
- gint src_space_cur_pos_y_i;
- gint src_space_row_start_x_i;
- gint src_space_row_start_y_i;
- const guchar *src_walker;
- const guchar *pixel_next;
- const guchar *pixel_below;
- const guchar *pixel_below_next;
- gint opposite_x, distance_from_true_x;
- gint opposite_y, distance_from_true_y;
/*
* tl, tr etc are used because it is easier to visualize top left,
@@ -229,8 +221,7 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
result = gimp_temp_buf_new (dest_width, dest_height,
gimp_temp_buf_get_format (source));
- dest = gimp_temp_buf_get_data (result);
- src = gimp_temp_buf_get_data (source);
+ src = gimp_temp_buf_get_data (source);
/* prevent disappearance of 1x1 pixel brush at some rotations when
scaling < 1 */
@@ -265,103 +256,124 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
src_walk_vx_i = (gint) ((src_tl_to_bl_delta_x / dest_height) * int_multiple);
src_walk_vy_i = (gint) ((src_tl_to_bl_delta_y / dest_height) * int_multiple);
- /* initialize current position in source space to the start position (tl)
- * speed optimized, note conversion to int precision
- */
- src_space_cur_pos_x_i = (gint) (t_lx* int_multiple);
- src_space_cur_pos_y_i = (gint) (t_ly* int_multiple);
- src_space_cur_pos_x = (gint) (src_space_cur_pos_x_i >> fraction_bits);
- src_space_cur_pos_y = (gint) (src_space_cur_pos_y_i >> fraction_bits);
- src_space_row_start_x_i = (gint) (t_lx* int_multiple);
- src_space_row_start_y_i = (gint) (t_ly* int_multiple);
-
-
- for (y = 0; y < dest_height; y++)
+ gimp_parallel_distribute_area (GEGL_RECTANGLE (0, 0, dest_width, dest_height),
+ MIN_PARALLEL_SUB_AREA,
+ [=] (const GeglRectangle *area)
{
- for (x = 0; x < dest_width; x++)
+ guchar *dest;
+ gint src_space_cur_pos_x;
+ gint src_space_cur_pos_y;
+ gint src_space_cur_pos_x_i;
+ gint src_space_cur_pos_y_i;
+ gint src_space_row_start_x_i;
+ gint src_space_row_start_y_i;
+ const guchar *src_walker;
+ const guchar *pixel_next;
+ const guchar *pixel_below;
+ const guchar *pixel_below_next;
+ gint opposite_x, distance_from_true_x;
+ gint opposite_y, distance_from_true_y;
+ gint u, v;
+
+ dest = gimp_temp_buf_get_data (result) +
+ dest_width * area->y + area->x;
+
+ /* initialize current position in source space to the start position (tl)
+ * speed optimized, note conversion to int precision
+ */
+ src_space_row_start_x_i = (gint) (t_lx * int_multiple) +
+ src_walk_vx_i * area->y +
+ src_walk_ux_i * area->x;
+ src_space_row_start_y_i = (gint) (t_ly * int_multiple) +
+ src_walk_vy_i * area->y +
+ src_walk_uy_i * area->x;
+
+ for (v = 0; v < area->height; v++)
{
- if (src_space_cur_pos_x > src_width_minus_one ||
- src_space_cur_pos_x < 0 ||
- src_space_cur_pos_y > src_height_minus_one ||
- src_space_cur_pos_y < 0)
- /* no corresponding pixel in source space */
- {
- *dest = 0;
- }
- else /* reverse transformed point hits source pixel */
- {
- src_walker = src
- + src_space_cur_pos_y * src_width
- + src_space_cur_pos_x;
-
- /* bottom right corner
- * no pixel below, reuse current pixel instead
- * no next pixel to the right so reuse current pixel instead
- */
- if (src_space_cur_pos_y == src_height_minus_one &&
- src_space_cur_pos_x == src_width_minus_one )
- {
- pixel_next = src_walker;
- pixel_below = src_walker;
- pixel_below_next = src_walker;
- }
+ src_space_cur_pos_x_i = src_space_row_start_x_i;
+ src_space_cur_pos_y_i = src_space_row_start_y_i;
- /* bottom edge pixel row, except rightmost corner
- * no pixel below, reuse current pixel instead */
- else if (src_space_cur_pos_y == src_height_minus_one)
+ for (u = 0; u < area->width; u++)
+ {
+ src_space_cur_pos_x = src_space_cur_pos_x_i >> fraction_bits;
+ src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
+
+ if (src_space_cur_pos_x > src_width_minus_one ||
+ src_space_cur_pos_x < 0 ||
+ src_space_cur_pos_y > src_height_minus_one ||
+ src_space_cur_pos_y < 0)
+ /* no corresponding pixel in source space */
{
- pixel_next = src_walker + 1;
- pixel_below = src_walker;
- pixel_below_next = src_walker + 1;
+ *dest = 0;
}
-
- /* right edge pixel column, except bottom corner
- * no next pixel to the right so reuse current pixel instead */
- else if (src_space_cur_pos_x == src_width_minus_one)
+ else /* reverse transformed point hits source pixel */
{
- pixel_next = src_walker;
- pixel_below = src_walker + src_width;
- pixel_below_next = pixel_below;
- }
+ src_walker = src +
+ src_space_cur_pos_y * src_width +
+ src_space_cur_pos_x;
+
+ /* bottom right corner
+ * no pixel below, reuse current pixel instead
+ * no next pixel to the right so reuse current pixel instead
+ */
+ if (src_space_cur_pos_y == src_height_minus_one &&
+ src_space_cur_pos_x == src_width_minus_one )
+ {
+ pixel_next = src_walker;
+ pixel_below = src_walker;
+ pixel_below_next = src_walker;
+ }
- /* neither on bottom edge nor on right edge */
- else
- {
- pixel_next = src_walker + 1;
- pixel_below = src_walker + src_width;
- pixel_below_next = pixel_below + 1;
- }
+ /* bottom edge pixel row, except rightmost corner
+ * no pixel below, reuse current pixel instead */
+ else if (src_space_cur_pos_y == src_height_minus_one)
+ {
+ pixel_next = src_walker + 1;
+ pixel_below = src_walker;
+ pixel_below_next = src_walker + 1;
+ }
- distance_from_true_x = src_space_cur_pos_x_i & fraction_bitmask;
- distance_from_true_y = src_space_cur_pos_y_i & fraction_bitmask;
- opposite_x = int_multiple - distance_from_true_x;
- opposite_y = int_multiple - distance_from_true_y;
+ /* right edge pixel column, except bottom corner
+ * no next pixel to the right so reuse current pixel instead */
+ else if (src_space_cur_pos_x == src_width_minus_one)
+ {
+ pixel_next = src_walker;
+ pixel_below = src_walker + src_width;
+ pixel_below_next = pixel_below;
+ }
- *dest = ((src_walker[0] * opposite_x +
- pixel_next[0] * distance_from_true_x) * opposite_y +
- (pixel_below[0] * opposite_x +
- pixel_below_next[0] *distance_from_true_x) * distance_from_true_y
- ) >> recovery_bits;
- }
+ /* neither on bottom edge nor on right edge */
+ else
+ {
+ pixel_next = src_walker + 1;
+ pixel_below = src_walker + src_width;
+ pixel_below_next = pixel_below + 1;
+ }
- src_space_cur_pos_x_i+=src_walk_ux_i;
- src_space_cur_pos_y_i+=src_walk_uy_i;
+ distance_from_true_x = src_space_cur_pos_x_i & fraction_bitmask;
+ distance_from_true_y = src_space_cur_pos_y_i & fraction_bitmask;
+ opposite_x = int_multiple - distance_from_true_x;
+ opposite_y = int_multiple - distance_from_true_y;
- src_space_cur_pos_x = src_space_cur_pos_x_i >> fraction_bits;
- src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
+ *dest = ((src_walker[0] * opposite_x +
+ pixel_next[0] * distance_from_true_x) * opposite_y +
+ (pixel_below[0] * opposite_x +
+ pixel_below_next[0] *distance_from_true_x) * distance_from_true_y
+ ) >> recovery_bits;
+ }
- dest ++;
- } /* end for x */
+ src_space_cur_pos_x_i += src_walk_ux_i;
+ src_space_cur_pos_y_i += src_walk_uy_i;
- src_space_row_start_x_i +=src_walk_vx_i;
- src_space_row_start_y_i +=src_walk_vy_i;
- src_space_cur_pos_x_i = src_space_row_start_x_i;
- src_space_cur_pos_y_i = src_space_row_start_y_i;
+ dest++;
+ } /* end for x */
- src_space_cur_pos_x = src_space_cur_pos_x_i >> fraction_bits;
- src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
+ src_space_row_start_x_i += src_walk_vx_i;
+ src_space_row_start_y_i += src_walk_vy_i;
- } /* end for y */
+ dest += dest_width - area->width;
+ } /* end for y */
+ });
gimp_brush_transform_blur (result, blur_radius);
@@ -408,7 +420,6 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
{
GimpTempBuf *result;
GimpTempBuf *source;
- guchar *dest;
const guchar *src;
GimpMatrix3 matrix;
gint src_width;
@@ -429,18 +440,6 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
gint src_walk_uy_i;
gint src_walk_vx_i;
gint src_walk_vy_i;
- gint src_space_cur_pos_x;
- gint src_space_cur_pos_y;
- gint src_space_cur_pos_x_i;
- gint src_space_cur_pos_y_i;
- gint src_space_row_start_x_i;
- gint src_space_row_start_y_i;
- const guchar *src_walker;
- const guchar *pixel_next;
- const guchar *pixel_below;
- const guchar *pixel_below_next;
- gint opposite_x, distance_from_true_x;
- gint opposite_y, distance_from_true_y;
/*
* tl, tr etc are used because it is easier to visualize top left,
@@ -448,7 +447,7 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
* rectangle.
*/
const gint fraction_bits = 12;
- const gint int_multiple = pow(2,fraction_bits);
+ const gint int_multiple = pow (2, fraction_bits);
/* In inner loop's bilinear calculation, two numbers that were each
* previously multiplied by int_multiple are multiplied together.
@@ -470,7 +469,7 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
* 2^9 = 0010 0000 0000
* 2^9 - 1 = 0001 1111 1111
*/
- const guint fraction_bitmask = pow(2, fraction_bits)- 1 ;
+ const guint fraction_bitmask = pow(2, fraction_bits) - 1 ;
source = gimp_brush_get_pixmap (brush);
@@ -483,7 +482,6 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
if (gimp_matrix3_is_identity (&matrix) && hardness == 1.0)
return gimp_temp_buf_copy (source);
-
src_width_minus_one = src_width - 1;
src_height_minus_one = src_height - 1;
@@ -523,8 +521,16 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
result = gimp_temp_buf_new (dest_width, dest_height,
gimp_temp_buf_get_format (source));
- dest = gimp_temp_buf_get_data (result);
- src = gimp_temp_buf_get_data (source);
+ src = gimp_temp_buf_get_data (source);
+
+ /* prevent disappearance of 1x1 pixel brush at some rotations when
+ scaling < 1 */
+ /*
+ if (src_width == 1 && src_height == 1 && scale_x < 1 && scale_y < 1 )
+ {
+ *dest = src[0];
+ return result;
+ }*/
gimp_matrix3_transform_point (&matrix, 0, 0, &t_lx, &t_ly);
gimp_matrix3_transform_point (&matrix, dest_width, 0, &t_rx, &t_ry);
@@ -545,122 +551,143 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
src_tl_to_bl_delta_y = b_ly - t_ly;
/* speed optimized, note conversion to int precision */
- src_walk_ux_i = (gint) ((src_tl_to_tr_delta_x / dest_width)* int_multiple);
- src_walk_uy_i = (gint) ((src_tl_to_tr_delta_y / dest_width)* int_multiple);
- src_walk_vx_i = (gint) ((src_tl_to_bl_delta_x / dest_height)* int_multiple);
- src_walk_vy_i = (gint) ((src_tl_to_bl_delta_y / dest_height)* int_multiple);
-
- /* initialize current position in source space to the start position (tl)
- * speed optimized, note conversion to int precision
- */
- src_space_cur_pos_x_i = (gint) (t_lx* int_multiple);
- src_space_cur_pos_y_i = (gint) (t_ly* int_multiple);
- src_space_cur_pos_x = (gint) (src_space_cur_pos_x_i >> fraction_bits);
- src_space_cur_pos_y = (gint) (src_space_cur_pos_y_i >> fraction_bits);
- src_space_row_start_x_i = (gint) (t_lx* int_multiple);
- src_space_row_start_y_i = (gint) (t_ly* int_multiple);
-
+ src_walk_ux_i = (gint) ((src_tl_to_tr_delta_x / dest_width) * int_multiple);
+ src_walk_uy_i = (gint) ((src_tl_to_tr_delta_y / dest_width) * int_multiple);
+ src_walk_vx_i = (gint) ((src_tl_to_bl_delta_x / dest_height) * int_multiple);
+ src_walk_vy_i = (gint) ((src_tl_to_bl_delta_y / dest_height) * int_multiple);
- for (y = 0; y < dest_height; y++)
+ gimp_parallel_distribute_area (GEGL_RECTANGLE (0, 0, dest_width, dest_height),
+ MIN_PARALLEL_SUB_AREA,
+ [=] (const GeglRectangle *area)
{
- for (x = 0; x < dest_width; x++)
+ guchar *dest;
+ gint src_space_cur_pos_x;
+ gint src_space_cur_pos_y;
+ gint src_space_cur_pos_x_i;
+ gint src_space_cur_pos_y_i;
+ gint src_space_row_start_x_i;
+ gint src_space_row_start_y_i;
+ const guchar *src_walker;
+ const guchar *pixel_next;
+ const guchar *pixel_below;
+ const guchar *pixel_below_next;
+ gint opposite_x, distance_from_true_x;
+ gint opposite_y, distance_from_true_y;
+ gint u, v;
+
+ dest = gimp_temp_buf_get_data (result) +
+ 3 * (dest_width * area->y + area->x);
+
+ /* initialize current position in source space to the start position (tl)
+ * speed optimized, note conversion to int precision
+ */
+ src_space_row_start_x_i = (gint) (t_lx * int_multiple) +
+ src_walk_vx_i * area->y +
+ src_walk_ux_i * area->x;
+ src_space_row_start_y_i = (gint) (t_ly * int_multiple) +
+ src_walk_vy_i * area->y +
+ src_walk_uy_i * area->x;
+
+ for (v = 0; v < area->height; v++)
{
- if (src_space_cur_pos_x > src_width_minus_one ||
- src_space_cur_pos_x < 0 ||
- src_space_cur_pos_y > src_height_minus_one ||
- src_space_cur_pos_y < 0)
- /* no corresponding pixel in source space */
- {
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- }
- else /* reverse transformed point hits source pixel */
+ src_space_cur_pos_x_i = src_space_row_start_x_i;
+ src_space_cur_pos_y_i = src_space_row_start_y_i;
+
+ for (u = 0; u < area->width; u++)
{
- src_walker = src
- + 3 * (
- src_space_cur_pos_y * src_width
- + src_space_cur_pos_x);
-
- /* bottom right corner
- * no pixel below, reuse current pixel instead
- * no next pixel to the right so reuse current pixel instead
- */
- if (src_space_cur_pos_y == src_height_minus_one &&
- src_space_cur_pos_x == src_width_minus_one )
+ src_space_cur_pos_x = src_space_cur_pos_x_i >> fraction_bits;
+ src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
+
+ if (src_space_cur_pos_x > src_width_minus_one ||
+ src_space_cur_pos_x < 0 ||
+ src_space_cur_pos_y > src_height_minus_one ||
+ src_space_cur_pos_y < 0)
+ /* no corresponding pixel in source space */
{
- pixel_next = src_walker;
- pixel_below = src_walker;
- pixel_below_next = src_walker;
+ dest[0] = 0;
+ dest[1] = 0;
+ dest[2] = 0;
}
-
- /* bottom edge pixel row, except rightmost corner
- * no pixel below, reuse current pixel instead */
- else if (src_space_cur_pos_y == src_height_minus_one)
+ else /* reverse transformed point hits source pixel */
{
- pixel_next = src_walker + 3;
- pixel_below = src_walker;
- pixel_below_next = src_walker + 3;
- }
+ src_walker = src +
+ 3 * (src_space_cur_pos_y * src_width +
+ src_space_cur_pos_x);
+
+ /* bottom right corner
+ * no pixel below, reuse current pixel instead
+ * no next pixel to the right so reuse current pixel instead
+ */
+ if (src_space_cur_pos_y == src_height_minus_one &&
+ src_space_cur_pos_x == src_width_minus_one )
+ {
+ pixel_next = src_walker;
+ pixel_below = src_walker;
+ pixel_below_next = src_walker;
+ }
- /* right edge pixel column, except bottom corner
- * no next pixel to the right so reuse current pixel instead */
- else if (src_space_cur_pos_x == src_width_minus_one)
- {
- pixel_next = src_walker;
- pixel_below = src_walker + src_width * 3;
- pixel_below_next = pixel_below;
- }
+ /* bottom edge pixel row, except rightmost corner
+ * no pixel below, reuse current pixel instead */
+ else if (src_space_cur_pos_y == src_height_minus_one)
+ {
+ pixel_next = src_walker + 3;
+ pixel_below = src_walker;
+ pixel_below_next = src_walker + 3;
+ }
- /* neither on bottom edge nor on right edge */
- else
- {
- pixel_next = src_walker + 3;
- pixel_below = src_walker + src_width * 3;
- pixel_below_next = pixel_below + 3;
- }
+ /* right edge pixel column, except bottom corner
+ * no next pixel to the right so reuse current pixel instead */
+ else if (src_space_cur_pos_x == src_width_minus_one)
+ {
+ pixel_next = src_walker;
+ pixel_below = src_walker + src_width * 3;
+ pixel_below_next = pixel_below;
+ }
- distance_from_true_x = src_space_cur_pos_x_i & fraction_bitmask;
- distance_from_true_y = src_space_cur_pos_y_i & fraction_bitmask;
- opposite_x = int_multiple - distance_from_true_x;
- opposite_y = int_multiple - distance_from_true_y;
-
- dest[0] = ((src_walker[0] * opposite_x +
- pixel_next[0] * distance_from_true_x) * opposite_y +
- (pixel_below[0] * opposite_x +
- pixel_below_next[0] *distance_from_true_x) * distance_from_true_y
- ) >> recovery_bits;
-
- dest[1] = ((src_walker[1] * opposite_x +
- pixel_next[1] * distance_from_true_x) * opposite_y +
- (pixel_below[1] * opposite_x +
- pixel_below_next[1] *distance_from_true_x) * distance_from_true_y
- ) >> recovery_bits;
-
- dest[2] = ((src_walker[2] * opposite_x +
- pixel_next[2] * distance_from_true_x) * opposite_y +
- (pixel_below[2] * opposite_x +
- pixel_below_next[2] *distance_from_true_x) * distance_from_true_y
- ) >> recovery_bits;
- }
+ /* neither on bottom edge nor on right edge */
+ else
+ {
+ pixel_next = src_walker + 3;
+ pixel_below = src_walker + src_width * 3;
+ pixel_below_next = pixel_below + 3;
+ }
- src_space_cur_pos_x_i += src_walk_ux_i;
- src_space_cur_pos_y_i += src_walk_uy_i;
+ distance_from_true_x = src_space_cur_pos_x_i & fraction_bitmask;
+ distance_from_true_y = src_space_cur_pos_y_i & fraction_bitmask;
+ opposite_x = int_multiple - distance_from_true_x;
+ opposite_y = int_multiple - distance_from_true_y;
+
+ dest[0] = ((src_walker[0] * opposite_x +
+ pixel_next[0] * distance_from_true_x) * opposite_y +
+ (pixel_below[0] * opposite_x +
+ pixel_below_next[0] *distance_from_true_x) * distance_from_true_y
+ ) >> recovery_bits;
+
+ dest[1] = ((src_walker[1] * opposite_x +
+ pixel_next[1] * distance_from_true_x) * opposite_y +
+ (pixel_below[1] * opposite_x +
+ pixel_below_next[1] *distance_from_true_x) * distance_from_true_y
+ ) >> recovery_bits;
+
+ dest[2] = ((src_walker[2] * opposite_x +
+ pixel_next[2] * distance_from_true_x) * opposite_y +
+ (pixel_below[2] * opposite_x +
+ pixel_below_next[2] *distance_from_true_x) * distance_from_true_y
+ ) >> recovery_bits;
+ }
- src_space_cur_pos_x = src_space_cur_pos_x_i >> fraction_bits;
- src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
+ src_space_cur_pos_x_i += src_walk_ux_i;
+ src_space_cur_pos_y_i += src_walk_uy_i;
- dest += 3;
- } /* end for x */
+ dest += 3;
+ } /* end for x */
- src_space_row_start_x_i +=src_walk_vx_i;
- src_space_row_start_y_i +=src_walk_vy_i;
- src_space_cur_pos_x_i = src_space_row_start_x_i;
- src_space_cur_pos_y_i = src_space_row_start_y_i;
+ src_space_row_start_x_i += src_walk_vx_i;
+ src_space_row_start_y_i += src_walk_vy_i;
- src_space_cur_pos_x = src_space_cur_pos_x_i >> fraction_bits;
- src_space_cur_pos_y = src_space_cur_pos_y_i >> fraction_bits;
- } /* end for y */
+ dest += 3 * (dest_width - area->width);
+ } /* end for y */
+ });
gimp_brush_transform_blur (result, blur_radius);
@@ -774,157 +801,177 @@ gimp_brush_transform_blur (GimpTempBuf *buf,
gfloat n_r = n * r;
gfloat weight = floor (n * n / 2) * (floor (n * n / 2) + 1);
gfloat weight_inv = 1 / weight;
- gint x;
- gint y;
- gint c;
Sums *sums;
- guchar *d;
- Sums *s;
if (rw <= 0 || rh <= 0)
return;
sums = g_new (Sums, width * height * components);
- d = data;
- s = sums;
-
- for (y = 0; y < height; y++)
+ gimp_parallel_distribute_range (height, MIN_PARALLEL_SUB_SIZE,
+ [=] (gint y0, gint height)
{
- const guchar *p;
+ gint x;
+ gint y;
+ gint c;
+ const guchar *d;
+ Sums *s;
- struct
- {
- gint sum;
- gint weighted_sum;
- gint leading_sum;
- gint leading_weighted_sum;
- } acc[components];
+ d = data + y0 * stride;
+ s = sums + y0 * stride;
- memset (acc, 0, sizeof (acc));
+ for (y = 0; y < height; y++)
+ {
+ const guchar *p;
- p = d;
+ struct
+ {
+ gint sum;
+ gint weighted_sum;
+ gint leading_sum;
+ gint leading_weighted_sum;
+ } acc[components];
- for (x = 0; x <= rw; x++)
- {
- for (c = 0; c < components; c++)
+ memset (acc, 0, sizeof (acc));
+
+ p = d;
+
+ for (x = 0; x <= rw; x++)
{
- acc[c].sum += *p;
- acc[c].weighted_sum += -x * *p;
+ for (c = 0; c < components; c++)
+ {
+ acc[c].sum += *p;
+ acc[c].weighted_sum += -x * *p;
- p++;
+ p++;
+ }
}
- }
- for (x = 0; x < width; x++)
- {
- for (c = 0; c < components; c++)
+ for (x = 0; x < width; x++)
{
- if (x > 0)
+ for (c = 0; c < components; c++)
{
- acc[c].weighted_sum += acc[c].sum;
- acc[c].leading_weighted_sum += acc[c].leading_sum;
-
- if (x < width - r)
+ if (x > 0)
{
- acc[c].sum += d[components_r];
- acc[c].weighted_sum += -r * d[components_r];
+ acc[c].weighted_sum += acc[c].sum;
+ acc[c].leading_weighted_sum += acc[c].leading_sum;
+
+ if (x < width - r)
+ {
+ acc[c].sum += d[components_r];
+ acc[c].weighted_sum += -r * d[components_r];
+ }
}
- }
- acc[c].leading_sum += d[0];
+ acc[c].leading_sum += d[0];
- s->sum = acc[c].sum;
- s->weighted_sum = acc[c].weighted_sum;
- s->middle_sum = 2 * acc[c].leading_weighted_sum -
- acc[c].weighted_sum;
+ s->sum = acc[c].sum;
+ s->weighted_sum = acc[c].weighted_sum;
+ s->middle_sum = 2 * acc[c].leading_weighted_sum -
+ acc[c].weighted_sum;
- if (x >= r)
- {
- acc[c].sum -= d[-components_r];
- acc[c].weighted_sum -= r * d[-components_r];
- acc[c].leading_sum -= d[-components_r];
- acc[c].leading_weighted_sum -= r * d[-components_r];
- }
+ if (x >= r)
+ {
+ acc[c].sum -= d[-components_r];
+ acc[c].weighted_sum -= r * d[-components_r];
+ acc[c].leading_sum -= d[-components_r];
+ acc[c].leading_weighted_sum -= r * d[-components_r];
+ }
- d++;
- s++;
+ d++;
+ s++;
+ }
}
}
- }
+ });
- for (x = 0; x < width; x++)
+ gimp_parallel_distribute_range (width, MIN_PARALLEL_SUB_SIZE,
+ [=] (gint x0, gint width)
{
- const Sums *p;
- gfloat n_y;
+ gint x;
+ gint y;
+ gint c;
+ guchar *d0;
+ const Sums *s0;
+ guchar *d;
+ const Sums *s;
- struct
- {
- gfloat weighted_sum;
- gint leading_sum;
- gint trailing_sum;
- } acc[components];
+ d0 = data + x0 * components;
+ s0 = sums + x0 * components;
- memset (acc, 0, sizeof (acc));
+ for (x = 0; x < width; x++)
+ {
+ const Sums *p;
+ gfloat n_y;
- d = data + components * x;
- s = sums + components * x;
+ struct
+ {
+ gfloat weighted_sum;
+ gint leading_sum;
+ gint trailing_sum;
+ } acc[components];
- p = s + stride;
+ memset (acc, 0, sizeof (acc));
- for (y = 1, n_y = n; y <= rh; y++, n_y += n)
- {
- for (c = 0; c < components; c++)
+ d = d0 + components * x;
+ s = s0 + components * x;
+
+ p = s + stride;
+
+ for (y = 1, n_y = n; y <= rh; y++, n_y += n)
{
- acc[c].weighted_sum += n_y * p->sum - p->weighted_sum;
- acc[c].trailing_sum += p->sum;
+ for (c = 0; c < components; c++)
+ {
+ acc[c].weighted_sum += n_y * p->sum - p->weighted_sum;
+ acc[c].trailing_sum += p->sum;
- p++;
- }
+ p++;
+ }
- p += stride - components;
- }
+ p += stride - components;
+ }
- for (y = 0; y < height; y++)
- {
- for (c = 0; c < components; c++)
+ for (y = 0; y < height; y++)
{
- if (y > 0)
+ for (c = 0; c < components; c++)
{
- acc[c].weighted_sum += s->weighted_sum +
- n * (acc[c].leading_sum -
- acc[c].trailing_sum);
- acc[c].trailing_sum -= s->sum;
-
- if (y < height - r)
+ if (y > 0)
{
- acc[c].weighted_sum += n_r * s[stride_r].sum -
- s[stride_r].weighted_sum;
- acc[c].trailing_sum += s[stride_r].sum;
+ acc[c].weighted_sum += s->weighted_sum +
+ n * (acc[c].leading_sum -
+ acc[c].trailing_sum);
+ acc[c].trailing_sum -= s->sum;
+
+ if (y < height - r)
+ {
+ acc[c].weighted_sum += n_r * s[stride_r].sum -
+ s[stride_r].weighted_sum;
+ acc[c].trailing_sum += s[stride_r].sum;
+ }
}
- }
- acc[c].leading_sum += s->sum;
+ acc[c].leading_sum += s->sum;
- *d = (acc[c].weighted_sum + s->middle_sum) * weight_inv + 0.5f;
+ *d = (acc[c].weighted_sum + s->middle_sum) * weight_inv + 0.5f;
- acc[c].weighted_sum += s->weighted_sum;
+ acc[c].weighted_sum += s->weighted_sum;
- if (y >= r)
- {
- acc[c].weighted_sum -= n_r * s[-stride_r].sum +
- s[-stride_r].weighted_sum;
- acc[c].leading_sum -= s[-stride_r].sum;
+ if (y >= r)
+ {
+ acc[c].weighted_sum -= n_r * s[-stride_r].sum +
+ s[-stride_r].weighted_sum;
+ acc[c].leading_sum -= s[-stride_r].sum;
+ }
+
+ d++;
+ s++;
}
- d++;
- s++;
+ d += stride - components;
+ s += stride - components;
}
-
- d += stride - components;
- s += stride - components;
}
- }
+ });
g_free (sums);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]