[gegl] algorithms: implement dedicated 2x2 downscale functions for u8 rgb and rgba
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] algorithms: implement dedicated 2x2 downscale functions for u8 rgb and rgba
- Date: Mon, 2 Apr 2018 12:09:02 +0000 (UTC)
commit 76e01bc2370c410c50dad17fd062630ef9012107
Author: Øyvind Kolås <pippin gimp org>
Date: Mon Apr 2 14:07:23 2018 +0200
algorithms: implement dedicated 2x2 downscale functions for u8 rgb and rgba
This avoids a couple of extra function calls, as well as avoids a switch per
scanline of tile which is a more significant saving.
gegl/gegl-algorithms.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
gegl/gegl-types-internal.h | 2 +
2 files changed, 111 insertions(+), 0 deletions(-)
---
diff --git a/gegl/gegl-algorithms.c b/gegl/gegl-algorithms.c
index a298394..760e460 100644
--- a/gegl/gegl-algorithms.c
+++ b/gegl/gegl-algorithms.c
@@ -823,6 +823,110 @@ gegl_downscale_2x2_u8_nl_alpha (const Babl *format,
#undef CASE
}
+static void
+gegl_downscale_2x2_u8_rgba (const Babl *format,
+ gint src_width,
+ gint src_height,
+ guchar *src_data,
+ gint src_rowstride,
+ guchar *dst_data,
+ gint dst_rowstride)
+{
+ gint y;
+ const gint bpp = 4;
+ gint diag = src_rowstride + bpp;
+
+ if (!src_data || !dst_data)
+ return;
+
+ for (y = 0; y < src_height / 2; y++)
+ {
+ gint x;
+ guchar *src = src_data + src_rowstride * y * 2;
+ guchar *dst = dst_data + dst_rowstride * y;
+
+ uint8_t * aa = ((uint8_t *)(src));
+ uint8_t * ab = ((uint8_t *)(src + bpp));
+ uint8_t * ba = ((uint8_t *)(src + src_rowstride));
+ uint8_t * bb = ((uint8_t *)(src + diag));
+
+ for (x = 0; x < src_width / 2; x++)
+ {
+
+ ((uint8_t *)dst)[0] = lut_u16_to_u8[ (lut_u8_to_u16[aa[0]] +
+ lut_u8_to_u16[ab[0]] +
+ lut_u8_to_u16[ba[0]] +
+ lut_u8_to_u16[bb[0]])>>2 ];
+ ((uint8_t *)dst)[1] = lut_u16_to_u8[ (lut_u8_to_u16[aa[1]] +
+ lut_u8_to_u16[ab[1]] +
+ lut_u8_to_u16[ba[1]] +
+ lut_u8_to_u16[bb[1]])>>2 ];
+ ((uint8_t *)dst)[2] = lut_u16_to_u8[ (lut_u8_to_u16[aa[2]] +
+ lut_u8_to_u16[ab[2]] +
+ lut_u8_to_u16[ba[2]] +
+ lut_u8_to_u16[bb[2]])>>2 ];
+ ((uint8_t *)dst)[3] = (aa[3] + ab[3] + ba[3] + bb[3])>>2;
+
+ dst += bpp;
+ aa += bpp * 2;
+ ab += bpp * 2;
+ ba += bpp * 2;
+ bb += bpp * 2;
+ }
+ }
+}
+
+static void
+gegl_downscale_2x2_u8_rgb (const Babl *format,
+ gint src_width,
+ gint src_height,
+ guchar *src_data,
+ gint src_rowstride,
+ guchar *dst_data,
+ gint dst_rowstride)
+{
+ gint y;
+ const gint bpp = 3;
+ gint diag = src_rowstride + bpp;
+
+ if (!src_data || !dst_data)
+ return;
+
+ for (y = 0; y < src_height / 2; y++)
+ {
+ gint x;
+ guchar *src = src_data + src_rowstride * y * 2;
+ guchar *dst = dst_data + dst_rowstride * y;
+
+ uint8_t * aa = ((uint8_t *)(src));
+ uint8_t * ab = ((uint8_t *)(src + bpp));
+ uint8_t * ba = ((uint8_t *)(src + src_rowstride));
+ uint8_t * bb = ((uint8_t *)(src + diag));
+
+ for (x = 0; x < src_width / 2; x++)
+ {
+
+ ((uint8_t *)dst)[0] = lut_u16_to_u8[ (lut_u8_to_u16[aa[0]] +
+ lut_u8_to_u16[ab[0]] +
+ lut_u8_to_u16[ba[0]] +
+ lut_u8_to_u16[bb[0]])>>2 ];
+ ((uint8_t *)dst)[1] = lut_u16_to_u8[ (lut_u8_to_u16[aa[1]] +
+ lut_u8_to_u16[ab[1]] +
+ lut_u8_to_u16[ba[1]] +
+ lut_u8_to_u16[bb[1]])>>2 ];
+ ((uint8_t *)dst)[2] = lut_u16_to_u8[ (lut_u8_to_u16[aa[2]] +
+ lut_u8_to_u16[ab[2]] +
+ lut_u8_to_u16[ba[2]] +
+ lut_u8_to_u16[bb[2]])>>2 ];
+ dst += bpp;
+ aa += bpp * 2;
+ ab += bpp * 2;
+ ba += bpp * 2;
+ bb += bpp * 2;
+ }
+ }
+}
+
GeglDownscale2x2Fun gegl_downscale_2x2_get_fun (const Babl *format)
{
@@ -854,6 +958,11 @@ GeglDownscale2x2Fun gegl_downscale_2x2_get_fun (const Babl *format)
}
if (comp_type == gegl_babl_u8())
{
+ if (format == gegl_babl_rgba_u8())
+ return gegl_downscale_2x2_u8_rgba;
+ if (format == gegl_babl_rgb_u8())
+ return gegl_downscale_2x2_u8_rgb;
+
if (babl_format_has_alpha (format))
return gegl_downscale_2x2_u8_nl_alpha;
else
diff --git a/gegl/gegl-types-internal.h b/gegl/gegl-types-internal.h
index 335c112..36a234b 100644
--- a/gegl/gegl-types-internal.h
+++ b/gegl/gegl-types-internal.h
@@ -96,6 +96,8 @@ static inline gboolean gegl_babl_model_is_linear (const Babl *babl)
}
GEGL_CACHED_BABL(format, rgba_float, "R'G'B'A float")
+GEGL_CACHED_BABL(format, rgba_u8, "R'G'B'A u8")
+GEGL_CACHED_BABL(format, rgb_u8, "R'G'B' u8")
GEGL_CACHED_BABL(format, rgbA_float, "R'aG'aB'aA float")
GEGL_CACHED_BABL(format, rgba_linear_float, "RGBA float")
GEGL_CACHED_BABL(format, rgba_linear_u16, "RGBA u16")
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]