[gegl] buffer: make bilinear interpolation from mipmap be default for scaled get
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: make bilinear interpolation from mipmap be default for scaled get
- Date: Sun, 28 Jan 2018 20:59:21 +0000 (UTC)
commit 8dd0bef29abd4bbb48994de5c7421637dce5149f
Author: Øyvind Kolås <pippin gimp org>
Date: Sun Jan 28 02:43:58 2018 +0100
buffer: make bilinear interpolation from mipmap be default for scaled get
gegl_buffer_get's last argument the repeat-mode is now a combined bit-field
flags argument. In addition to choosing the edge repeat behavior for the fetch
we can now also control the interpolation used when scaling from the nearest
bigger mipmap level explicitly by oring one of the buffer scaling modes into
the flags.
The available values that can be | in with the repeat-mode, are, with the
performance scaling factors relative to the default, GEGL_BUFFER_BILINEAR, note
that for the range 0-2.0 the default is boxfilter - since it is a nicer
transition to nearest neighbor.
GEGL_BUFFER_NEAREST 8.0
GEGL_BUFFER_BILINEAR 1.0
GEGL_BUFFER_BOXFILTER 0.4
nearest uses nearest neighbor sampling from the next bigger size, bilinear uses
a bilinear interpolation of the values from the bigger available size, sampling
2x2 pixels for each output pixel, while boxfilter uses a 3x3 neighbourhood -
which is sufficient for accurate box-filtering from the next bigger power of
two scale in a mip-map.
The names for these flags, in particular the prefix, might change, if neither
of them are passed in GEGL_BUFFER_BILINEAR is assumed, this is slightly lower
quality than the previoux default boxfilter, but is 5-6 times faster - while
still being much better than nearest neighbor - and as we are zooming out; the
more correct mipmap scaling dominates.
gegl/buffer/gegl-buffer-access.c | 23 +++++++++++++++++------
gegl/gegl-enums.h | 5 +++--
2 files changed, 20 insertions(+), 8 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 7400213..785c69c 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -1889,11 +1889,22 @@ _gegl_buffer_get_unlocked (GeglBuffer *buffer,
const Babl *format,
gpointer dest_buf,
gint rowstride,
- GeglAbyssPolicy repeat_mode)
+ GeglAbyssPolicy flags)
{
- gboolean do_nearest = (repeat_mode & GEGL_BUFFER_NEAREST) != 0;
- gboolean do_bilinear = (repeat_mode & GEGL_BUFFER_BILINEAR) != 0;
- repeat_mode &= 0x7;
+ GeglAbyssPolicy repeat_mode = flags & 0x7; /* mask off interpolation from repeat mode part of flags */
+ gint interpolation = (flags & GEGL_BUFFER_BOXFILTER); /* BOXFILTER is and of all interpols */
+
+ if (interpolation == 0)
+ {
+ /* with no specified interpolation we aim for a trade-off where
+ 100-200% ends up using box-filter - which is a better transition
+ to nearest neighbor which happens beyond 200% further below.
+ */
+ if (scale > 1.0)
+ interpolation = GEGL_BUFFER_BOXFILTER;
+ else
+ interpolation = GEGL_BUFFER_BILINEAR; /*about 2x as fast as box filter*/
+ }
if (gegl_cl_is_accelerated ())
{
@@ -2007,9 +2018,9 @@ _gegl_buffer_get_unlocked (GeglBuffer *buffer,
buf_width = x2 - x1;
buf_height = y2 - y1;
- if (!do_nearest && scale <= 1.99)
+ if ((interpolation != GEGL_BUFFER_NEAREST) && scale <= 1.99)
{
- if (do_bilinear)
+ if (interpolation == GEGL_BUFFER_BILINEAR)
{
buf_width += 1;
buf_height += 1;
diff --git a/gegl/gegl-enums.h b/gegl/gegl-enums.h
index 9fcee42..4d8aa81 100644
--- a/gegl/gegl-enums.h
+++ b/gegl/gegl-enums.h
@@ -42,8 +42,9 @@ typedef enum {
GEGL_ABYSS_LOOP = 2,
GEGL_ABYSS_BLACK = 3,
GEGL_ABYSS_WHITE = 4,
- GEGL_BUFFER_NEAREST = 32,
- GEGL_BUFFER_BILINEAR = 64
+ GEGL_BUFFER_BILINEAR = 16,
+ GEGL_BUFFER_NEAREST = 32,
+ GEGL_BUFFER_BOXFILTER = 48,
} GeglAbyssPolicy;
GType gegl_abyss_policy_get_type (void) G_GNUC_CONST;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]