[gegl] gegl: implement bilinear scaling code paths
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gegl: implement bilinear scaling code paths
- Date: Sun, 28 Jan 2018 20:59:01 +0000 (UTC)
commit d0abc7dc3a34d55fd5c5afa57229ea0ddfc3c49f
Author: Øyvind Kolås <pippin gimp org>
Date: Sat Jan 27 22:08:01 2018 +0100
gegl: implement bilinear scaling code paths
There was an unused, untested skeleton implementation, replace with an
implementation using tricks learned in other implementations.
gegl/gegl-algorithms-bilinear.inc | 203 +++++++++++++-----------------
gegl/gegl-algorithms.c | 245 +++++++++++++++++++++++++------------
2 files changed, 253 insertions(+), 195 deletions(-)
---
diff --git a/gegl/gegl-algorithms-bilinear.inc b/gegl/gegl-algorithms-bilinear.inc
index 9635135..1afc62f 100644
--- a/gegl/gegl-algorithms-bilinear.inc
+++ b/gegl/gegl-algorithms-bilinear.inc
@@ -8,130 +8,103 @@ BILINEAR_FUNCNAME (guchar *dest_buf,
const gint bpp,
const gint d_rowstride)
{
- const BILINEAR_TYPE *src[4];
- gint components = bpp / sizeof(BILINEAR_TYPE);
+ const gint components = bpp / sizeof(BILINEAR_TYPE);
+ const gint ver = s_rowstride/(bpp/components);
+ const gint diag = ver + components;
gfloat dx[dst_rect->width];
gint jj[dst_rect->width];
for (gint x = 0; x < dst_rect->width; x++)
{
- gfloat sx = (dst_rect->x + x + .5) / scale - src_rect->x;
+ gfloat sx = (dst_rect->x + x) / scale - src_rect->x;
jj[x] = int_floorf (sx);
dx[x] = sx - jj[x];
jj[x] *= components;
}
-
- for (gint y = 0; y < dst_rect->height; y++)
- {
- const gfloat sy = (dst_rect->y + y + .5) / scale - src_rect->y;
- const gint ii = int_floorf (sy);
- const gfloat dy = (sy - ii);
- const gfloat rdy = 1.0 - dy;
- BILINEAR_TYPE *dst = (BILINEAR_TYPE*)(dest_buf + y * d_rowstride);
- const guchar *src_base = source_buf + ii * s_rowstride;
-
- switch (components)
- {
- case 4:
- for (gint x = 0; x < dst_rect->width; x++)
- {
- src[0] = src[1] = src[2] = src[3] = (const BILINEAR_TYPE*)src_base + jj[x];
- src[1] += 4;
- src[2] += s_rowstride;
- src[3] += s_rowstride + 4;
-
- if (src[0][3] == 0 && /* XXX: it would be even better to not call this at all for the abyss...
*/
- src[1][3] == 0 &&
- src[2][3] == 0 &&
- src[3][3] == 0)
- {
- dst[0] = dst[1] = dst[2] = dst[3] = 0;
- }
- else
- {
- dst[0] = BILINEAR_ROUND(
- (src[0][0] * (1.0-dx[x]) + src[1][0] * (dx[x])) * (rdy) +
- (src[2][0] * (1.0-dx[x]) + src[3][0] * (dx[x])) * (dy));
- dst[1] = BILINEAR_ROUND(
- (src[0][1] * (1.0-dx[x]) + src[1][1] * (dx[x])) * (rdy) +
- (src[2][1] * (1.0-dx[x]) + src[3][1] * (dx[x])) * (dy));
- dst[2] = BILINEAR_ROUND(
- (src[0][2] * (1.0-dx[x]) + src[1][2] * (dx[x])) * (rdy) +
- (src[2][2] * (1.0-dx[x]) + src[3][2] * (dx[x])) * (dy));
- dst[3] = BILINEAR_ROUND(
- (src[0][3] * (1.0-dx[x]) + src[1][3] * (dx[x])) * (rdy) +
- (src[2][3] * (1.0-dx[x]) + src[3][3] * (dx[x])) * (dy));
- }
- dst += 4;
- }
- break;
- case 3:
- for (gint x = 0; x < dst_rect->width; x++)
- {
- src[0] = src[1] = src[2] = src[3] = (const BILINEAR_TYPE*)src_base + jj[x];
- src[1] += 3;
- src[2] += s_rowstride;
- src[3] += s_rowstride + 3;
- dst[0] = BILINEAR_ROUND(
- (src[0][0] * (1.0-dx[x]) + src[1][0] * (dx[x])) * (rdy) +
- (src[2][0] * (1.0-dx[x]) + src[3][0] * (dx[x])) * (dy));
- dst[1] = BILINEAR_ROUND(
- (src[0][1] * (1.0-dx[x]) + src[1][1] * (dx[x])) * (rdy) +
- (src[2][1] * (1.0-dx[x]) + src[3][1] * (dx[x])) * (dy));
- dst[2] = BILINEAR_ROUND(
- (src[0][2] * (1.0-dx[x]) + src[1][2] * (dx[x])) * (rdy) +
- (src[2][2] * (1.0-dx[x]) + src[3][2] * (dx[x])) * (dy));
- dst += 3;
- }
- break;
- case 2:
- for (gint x = 0; x < dst_rect->width; x++)
- {
- src[0] = src[1] = src[2] = src[3] = (const BILINEAR_TYPE*)src_base + jj[x];
- src[1] += 2;
- src[2] += s_rowstride;
- src[3] += s_rowstride + 2;
- dst[0] = BILINEAR_ROUND(
- (src[0][0] * (1.0-dx[x]) + src[1][0] * (dx[x])) * (rdy) +
- (src[2][0] * (1.0-dx[x]) + src[3][0] * (dx[x])) * (dy));
- dst[1] = BILINEAR_ROUND(
- (src[0][1] * (1.0-dx[x]) + src[1][1] * (dx[x])) * (rdy) +
- (src[2][1] * (1.0-dx[x]) + src[3][1] * (dx[x])) * (dy));
- dst += 2;
- }
- break;
- case 1:
- for (gint x = 0; x < dst_rect->width; x++)
- {
- src[0] = src[1] = src[2] = src[3] = (const BILINEAR_TYPE*)src_base + jj[x];
- src[1] += 1;
- src[2] += s_rowstride;
- src[3] += s_rowstride + 1;
- dst[0] = BILINEAR_ROUND(
- (src[0][0] * (1.0-dx[x]) + src[1][0] * (dx[x])) * (rdy) +
- (src[2][0] * (1.0-dx[x]) + src[3][0] * (dx[x])) * (dy));
- dst += 1;
- }
- break;
- default:
- for (gint x = 0; x < dst_rect->width; x++)
+#define IMPL(...) do{ \
+ for (gint y = 0; y < dst_rect->height; y++)\
+ {\
+ const gfloat sy = (dst_rect->y + y) / scale - src_rect->y;\
+ const gint ii = int_floorf (sy);\
+ const gfloat dy = (sy - ii);\
+ const gfloat rdy = 1.0 - dy;\
+ BILINEAR_TYPE *dst = (BILINEAR_TYPE*)(dest_buf + y * d_rowstride);\
+ const guchar *src_base = source_buf + ii * s_rowstride;\
+\
+ for (gint x = 0; x < dst_rect->width; x++)\
+ {\
+ const gfloat ldx = dx[x];\
+ const gfloat rdx = 1.0f-ldx;\
+ const BILINEAR_TYPE *src[4];\
+ src[0] = src[1] = src[2] = src[3] = \
+ (const BILINEAR_TYPE*)(src_base) + jj[x];\
+ src[1] += components;\
+ src[2] += ver;\
+ src[3] += diag;\
+ __VA_ARGS__;\
+ dst += components;\
+ }\
+ }\
+}while(0)
+ switch (components)
+ {
+ default:
+ IMPL(
+ for (gint i = 0; i < components; ++i)
{
- src[0] = src[1] = src[2] = src[3] = (const BILINEAR_TYPE*)src_base + jj[x];
- src[1] += components;
- src[2] += s_rowstride;
- src[3] += s_rowstride + components;
- {
- for (gint i = 0; i < components; ++i)
- {
- dst[i] = BILINEAR_ROUND(
- (src[0][i] * (1.0-dx[x]) + src[1][i] * (dx[x])) * (rdy) +
- (src[2][i] * (1.0-dx[x]) + src[3][i] * (dx[x])) * (dy));
- }
- }
- dst += components;
- }
- break;
- }
- }
+ dst[i] =
+ BILINEAR_ROUND(
+ (src[0][i] * (rdx) + src[1][i] * (ldx)) * (rdy) +
+ (src[2][i] * (rdx) + src[3][i] * (ldx)) * (dy));
+ });
+ break;
+ case 1:
+ IMPL( dst[0] =
+ BILINEAR_ROUND(
+ (src[0][0] * (rdx) + src[1][0] * (ldx)) * (rdy) +
+ (src[2][0] * (rdx) + src[3][0] * (ldx)) * (dy));
+ );
+ break;
+ case 2:
+ IMPL(
+ dst[0] = BILINEAR_ROUND(
+ (src[0][0] * (rdx) + src[1][0] * (ldx)) * (rdy) +
+ (src[2][0] * (rdx) + src[3][0] * (ldx)) * (dy));
+ dst[1] = BILINEAR_ROUND(
+ (src[0][1] * (rdx) + src[1][1] * (ldx)) * (rdy) +
+ (src[2][1] * (rdx) + src[3][1] * (ldx)) * (dy));
+ );
+ break;
+ case 3:
+ IMPL(
+ dst[0] = BILINEAR_ROUND(
+ (src[0][0] * (rdx) + src[1][0] * (ldx)) * (rdy) +
+ (src[2][0] * (rdx) + src[3][0] * (ldx)) * (dy));
+ dst[1] = BILINEAR_ROUND(
+ (src[0][1] * (rdx) + src[1][1] * (ldx)) * (rdy) +
+ (src[2][1] * (rdx) + src[3][1] * (ldx)) * (dy));
+ dst[2] = BILINEAR_ROUND(
+ (src[0][2] * (rdx) + src[1][2] * (ldx)) * (rdy) +
+ (src[2][2] * (rdx) + src[3][2] * (ldx)) * (dy));
+ );
+ break;
+ case 4:
+ IMPL(
+ dst[0] = BILINEAR_ROUND(
+ (src[0][0] * (rdx) + src[1][0] * (ldx)) * (rdy) +
+ (src[2][0] * (rdx) + src[3][0] * (ldx)) * (dy));
+ dst[1] = BILINEAR_ROUND(
+ (src[0][1] * (rdx) + src[1][1] * (ldx)) * (rdy) +
+ (src[2][1] * (rdx) + src[3][1] * (ldx)) * (dy));
+ dst[2] = BILINEAR_ROUND(
+ (src[0][2] * (rdx) + src[1][2] * (ldx)) * (rdy) +
+ (src[2][2] * (rdx) + src[3][2] * (ldx)) * (dy));
+ dst[3] = BILINEAR_ROUND(
+ (src[0][3] * (rdx) + src[1][3] * (ldx)) * (rdy) +
+ (src[2][3] * (rdx) + src[3][3] * (ldx)) * (dy));
+ );
+ break;
+ }
+#undef IMPL
}
diff --git a/gegl/gegl-algorithms.c b/gegl/gegl-algorithms.c
index bc68cb3..526d18f 100644
--- a/gegl/gegl-algorithms.c
+++ b/gegl/gegl-algorithms.c
@@ -195,7 +195,6 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
gint components = bpp / sizeof(uint8_t);
gfloat left_weight[dst_rect->width];
- //gfloat center_weight[dst_rect->width];
gfloat right_weight[dst_rect->width];
gint jj[dst_rect->width];
@@ -209,7 +208,6 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
left_weight[x] = MAX (0.0, left_weight[x]);
right_weight[x] = .5 - scale * ((jj[x] + 1) - sx);
right_weight[x] = MAX (0.0, right_weight[x]);
- //center_weight[x] = 1. - left_weight[x] - right_weight[x];
jj[x] *= components;
}
@@ -264,7 +262,7 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
const gfloat m = middle_weight;
const gfloat b = bottom_weight;
-#define BOXFILTER_ROUND(val) lut_u16_to_u8[((int)((val)+0.5))]
+#define BOXFILTER_ROUND(val) lut_u16_to_u8[((int)((val)+0.5f))]
#define C(val) lut_u8_to_u16[(val)]
dst[0] = BOXFILTER_ROUND(
(C(src[0][0]) * t + C(src[3][0]) * m + C(src[6][0]) * b) * l +
@@ -290,8 +288,8 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
for (gint x = 0; x < dst_rect->width; x++)
{
src[4] = (const uint8_t*)src_base + jj[x];
- src[1] = (const uint8_t*)(src_base - s_rowstride) + jj[x];
- src[7] = (const uint8_t*)(src_base + s_rowstride) + jj[x];
+ src[1] = src[4] - s_rowstride;
+ src[7] = src[4] + s_rowstride;
src[2] = src[1] + 3;
src[5] = src[4] + 3;
src[8] = src[7] + 3;
@@ -327,8 +325,8 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
for (gint x = 0; x < dst_rect->width; x++)
{
src[4] = (const uint8_t*)src_base + jj[x];
- src[1] = (const uint8_t*)(src_base - s_rowstride) + jj[x];
- src[7] = (const uint8_t*)(src_base + s_rowstride) + jj[x];
+ src[1] = src[4] - s_rowstride;
+ src[7] = src[4] + s_rowstride;
src[2] = src[1] + 2;
src[5] = src[4] + 2;
src[8] = src[7] + 2;
@@ -360,8 +358,8 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
for (gint x = 0; x < dst_rect->width; x++)
{
src[4] = (const uint8_t*)src_base + jj[x];
- src[1] = (const uint8_t*)(src_base - s_rowstride) + jj[x];
- src[7] = (const uint8_t*)(src_base + s_rowstride) + jj[x];
+ src[1] = src[4] - s_rowstride;
+ src[7] = src[4] + s_rowstride;
src[2] = src[1] + 1;
src[5] = src[4] + 1;
src[8] = src[7] + 1;
@@ -390,8 +388,8 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
for (gint x = 0; x < dst_rect->width; x++)
{
src[4] = (const uint8_t*)src_base + jj[x];
- src[1] = (const uint8_t*)(src_base - s_rowstride) + jj[x];
- src[7] = (const uint8_t*)(src_base + s_rowstride) + jj[x];
+ src[1] = src[4] - s_rowstride;
+ src[7] = src[4] + s_rowstride;
src[2] = src[1] + components;
src[5] = src[4] + components;
src[8] = src[7] + components;
@@ -425,6 +423,135 @@ gegl_boxfilter_u8_nl (guchar *dest_buf,
#undef C
static void
+gegl_bilinear_u8_nl (guchar *dest_buf,
+ const guchar *source_buf,
+ const GeglRectangle *dst_rect,
+ const GeglRectangle *src_rect,
+ const gint s_rowstride,
+ const gdouble scale,
+ const gint components,
+ const gint d_rowstride)
+{
+ const gint ver = s_rowstride;
+ const gint diag = ver + components;
+ const gint dst_y = dst_rect->y;
+ const gint src_y = src_rect->y;
+ const gint dst_width = dst_rect->width;
+ const gint dst_height = dst_rect->height;
+ gfloat dx[dst_rect->width];
+ gint jj[dst_rect->width];
+
+ for (gint x = 0; x < dst_rect->width; x++)
+ {
+ gfloat sx = (dst_rect->x + x ) / scale - src_rect->x;
+ jj[x] = int_floorf (sx);
+ dx[x] = (sx - jj[x]);
+ jj[x] *= components;
+ }
+#define IMPL(components, ...) do{ \
+ for (gint y = 0; y < dst_height; y++)\
+ {\
+ const gfloat sy = (dst_y + y ) / scale - src_y;\
+ const gint ii = int_floorf (sy);\
+ const gfloat dy = (sy - ii);\
+ const gfloat rdy = 1.0f - dy;\
+ guchar *dst = (guchar*)(dest_buf + y * d_rowstride);\
+ const guchar *src_base = source_buf + ii * s_rowstride;\
+ gfloat *idx=&dx[0];\
+ gint *ijj=&jj[0];\
+\
+ for (gint x = 0; x < dst_width; x++)\
+ {\
+ const gfloat ldx = *(idx++);\
+ const gfloat rdx = 1.0f-ldx;\
+ const guchar *src[4];\
+ src[0] = (const guchar*)(src_base) + *(ijj++);\
+ src[1] = src[0] + components;\
+ src[2] = src[0] + ver;\
+ src[3] = src[0] + diag;\
+ __VA_ARGS__;\
+ dst += components;\
+ }\
+ }\
+}while(0)
+
+#define BILINEAR_ROUND(val) lut_u16_to_u8[int_floorf(val)]
+#define C(val) lut_u8_to_u16[(val)]
+
+ switch (components)
+ {
+ default:
+ IMPL(components,
+ for (gint i = 0; i < components; ++i)
+ dst[i] =
+ BILINEAR_ROUND(
+ (C(src[0][i]) * rdx + C(src[1][i]) * ldx) * rdy +
+ (C(src[2][i]) * rdx + C(src[3][i]) * ldx) * dy);
+ );
+ break;
+ case 1:
+ IMPL(1,
+ dst[0] = BILINEAR_ROUND(
+ (C(src[0][0]) * rdx + C(src[1][0]) * ldx) * rdy +
+ (C(src[2][0]) * rdx + C(src[3][0]) * ldx) * dy);
+ );
+ break;
+ case 2:
+ IMPL(2,
+ dst[0] = BILINEAR_ROUND(
+ (C(src[0][0]) * rdx + C(src[1][0]) * ldx) * rdy +
+ (C(src[2][0]) * rdx + C(src[3][0]) * ldx) * dy);
+ dst[1] = BILINEAR_ROUND(
+ (C(src[0][1]) * rdx + C(src[1][1]) * ldx) * rdy +
+ (C(src[2][1]) * rdx + C(src[3][1]) * ldx) * dy);
+ );
+ break;
+ case 3:
+ IMPL(3,
+ dst[0] = BILINEAR_ROUND(
+ (C(src[0][0]) * rdx + C(src[1][0]) * ldx) * rdy +
+ (C(src[2][0]) * rdx + C(src[3][0]) * ldx) * dy);
+ dst[1] = BILINEAR_ROUND(
+ (C(src[0][1]) * rdx + C(src[1][1]) * ldx) * rdy +
+ (C(src[2][1]) * rdx + C(src[3][1]) * ldx) * dy);
+ dst[2] = BILINEAR_ROUND(
+ (C(src[0][2]) * rdx + C(src[1][2]) * ldx) * rdy +
+ (C(src[2][2]) * rdx + C(src[3][2]) * ldx) * dy);
+ );
+ break;
+ case 4:
+ IMPL(4,
+ if (src[0][3] == 0 &&
+ src[1][3] == 0 &&
+ src[2][3] == 0 &&
+ src[3][3] == 0)
+ {
+ (*(uint32_t*)(dst)) = 0;
+ }
+ else
+ {
+ dst[0] = BILINEAR_ROUND(
+ (C(src[0][0]) * rdx + C(src[1][0]) * ldx) * rdy +
+ (C(src[2][0]) * rdx + C(src[3][0]) * ldx) * dy);
+ dst[1] = BILINEAR_ROUND(
+ (C(src[0][1]) * rdx + C(src[1][1]) * ldx) * rdy +
+ (C(src[2][1]) * rdx + C(src[3][1]) * ldx) * dy);
+ dst[2] = BILINEAR_ROUND(
+ (C(src[0][2]) * rdx + C(src[1][2]) * ldx) * rdy +
+ (C(src[2][2]) * rdx + C(src[3][2]) * ldx) * dy);
+ dst[3] = BILINEAR_ROUND(
+ (C(src[0][3]) * rdx + C(src[1][3]) * ldx) * rdy +
+ (C(src[2][3]) * rdx + C(src[3][3]) * ldx) * dy);
+ }
+ );
+ break;
+ }
+#undef IMPL
+}
+#undef BILINEAR_ROUND
+#undef C
+
+static void
gegl_downscale_2x2_u8_nl (const Babl *format,
gint src_width,
gint src_height,
@@ -629,57 +756,6 @@ gegl_downscale_2x2_nearest (const Babl *format,
}
static void
-gegl_resample_boxfilter_generic_u16 (guchar *dest_buf,
- const guchar *source_buf,
- const GeglRectangle *dst_rect,
- const GeglRectangle *src_rect,
- gint s_rowstride,
- gdouble scale,
- const Babl *format,
- gint d_rowstride)
-{
- gint components = babl_format_get_n_components (format);
- const gint tmp_bpp = 4 * 2;
- gint in_tmp_rowstride = src_rect->width * tmp_bpp;
- gint out_tmp_rowstride = dst_rect->width * tmp_bpp;
- gint do_free = 0;
-
- guchar *in_tmp, *out_tmp;
-
- if (src_rect->height * in_tmp_rowstride + dst_rect->height * out_tmp_rowstride < GEGL_ALLOCA_THRESHOLD)
- {
- in_tmp = alloca (src_rect->height * in_tmp_rowstride);
- out_tmp = alloca (dst_rect->height * out_tmp_rowstride);
- }
- else
- {
- in_tmp = gegl_malloc (src_rect->height * in_tmp_rowstride);
- out_tmp = gegl_malloc (dst_rect->height * out_tmp_rowstride);
- do_free = 1;
- }
-
- u8_to_u16_rows (components,
- source_buf, s_rowstride,
- (void*)in_tmp, in_tmp_rowstride,
- src_rect->width, src_rect->height);
-
- gegl_resample_boxfilter_u16 (out_tmp, in_tmp, dst_rect, src_rect,
- in_tmp_rowstride, scale, tmp_bpp, out_tmp_rowstride);
-
- u16_to_u8_rows (components,
- (void*)out_tmp, out_tmp_rowstride,
- dest_buf, d_rowstride,
- dst_rect->width, dst_rect->height);
-
- if (do_free)
- {
- gegl_free (in_tmp);
- gegl_free (out_tmp);
- }
-}
-
-
-static void
gegl_resample_boxfilter_generic (guchar *dest_buf,
const guchar *source_buf,
const GeglRectangle *dst_rect,
@@ -770,15 +846,15 @@ void gegl_resample_boxfilter (guchar *dest_buf,
else
{
if (comp_type == gegl_babl_u8())
- gegl_boxfilter_u8_nl (dest_buf, source_buf, dst_rect, src_rect,
- s_rowstride, scale, bpp, d_rowstride);
-#if 0
- gegl_resample_boxfilter_generic_u16 (dest_buf, source_buf, dst_rect, src_rect,
- s_rowstride, scale, format, d_rowstride);
-#endif
+ {
+ gegl_boxfilter_u8_nl (dest_buf, source_buf, dst_rect, src_rect,
+ s_rowstride, scale, bpp, d_rowstride);
+ }
else
+ {
gegl_resample_boxfilter_generic (dest_buf, source_buf, dst_rect, src_rect,
s_rowstride, scale, format, d_rowstride);
+ }
}
}
@@ -846,10 +922,9 @@ void gegl_resample_bilinear (guchar *dest_buf,
gint d_rowstride)
{
const Babl *model = babl_format_get_model (format);
-
+ const Babl *comp_type = babl_format_get_type (format, 0);
if (gegl_babl_model_is_linear (model))
{
- const Babl *comp_type = babl_format_get_type (format, 0);
const gint bpp = babl_format_get_bytes_per_pixel (format);
if (comp_type == gegl_babl_float ())
@@ -873,8 +948,17 @@ void gegl_resample_bilinear (guchar *dest_buf,
}
else
{
+ if (comp_type == gegl_babl_u8 ())
+ {
+ const gint bpp = babl_format_get_bytes_per_pixel (format);
+ gegl_bilinear_u8_nl (dest_buf, source_buf, dst_rect, src_rect,
+ s_rowstride, scale, bpp, d_rowstride);
+ }
+ else
+ {
gegl_resample_bilinear_generic (dest_buf, source_buf, dst_rect, src_rect,
s_rowstride, scale, format, d_rowstride);
+ }
}
}
@@ -893,7 +977,7 @@ gegl_resample_nearest (guchar *dst,
for (x = 0; x < dst_rect->width; x++)
{
const gfloat sx = (dst_rect->x + .5 + x) / scale - src_rect->x;
- jj[x] = int_floorf (sx + GEGL_SCALE_EPSILON);
+ jj[x] = int_floorf (sx + GEGL_SCALE_EPSILON) * bpp;
}
#define IMPL(...) do{ \
@@ -901,6 +985,7 @@ gegl_resample_nearest (guchar *dst,
{\
const gfloat sy = (dst_rect->y + .5 + y) / scale - src_rect->y;\
const gint ii = int_floorf (sy + GEGL_SCALE_EPSILON);\
+ gint *ijj = &jj[0];\
guchar *d = &dst[y*dst_stride];\
const guchar *s = &src[ii * src_stride];\
for (x = 0; x < dst_rect->width; x++)\
@@ -914,43 +999,43 @@ gegl_resample_nearest (guchar *dst,
switch(bpp)
{
case 1:IMPL(
- d[0] = s[jj[x] * bpp];
+ d[0] = s[*(ijj++)];
);
break;
case 2:IMPL(
uint16_t* d16 = (void*) d;
- const uint16_t* s16 = (void*) &s[jj[x] * bpp];
+ const uint16_t* s16 = (void*) &s[*(ijj++)];
d16[0] = s16[0];
);
break;
case 3:IMPL(
- d[0] = s[jj[x] * bpp];
- d[1] = s[jj[x] * bpp + 1];
- d[2] = s[jj[x] * bpp + 2];
+ d[0] = s[*ijj];
+ d[1] = s[*ijj + 1];
+ d[2] = s[*(ijj++) + 2];
);
break;
case 4:IMPL(
uint32_t* d32 = (void*) d;
- const uint32_t* s32 = (void*) &s[jj[x] * bpp];
+ const uint32_t* s32 = (void*) &s[*(ijj++)];
d32[0] = s32[0];
);
break;
case 8:IMPL(
uint64_t* d64 = (void*) d;
- const uint64_t* s64 = (void*) &s[jj[x] * bpp];
+ const uint64_t* s64 = (void*) &s[*(ijj++)];
d64[0] = s64[0];
);
break;
case 16:IMPL(
uint64_t* d64 = (void*) d;
- const uint64_t* s64 = (void*) &s[jj[x] * bpp];
+ const uint64_t* s64 = (void*) &s[*(ijj++)];
d64[0] = s64[0];
d64[1] = s64[1];
);
break;
default:
IMPL(
- memcpy (&d[0], &s[jj[x] * bpp], bpp);
+ memcpy (&d[0], &s[*(ijj++)], bpp);
);
break;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]