Commit 9c3a4988 authored by Daniel Sabo's avatar Daniel Sabo

Move downscale functions out of tile-handler-zoom

parent 953d73f7
......@@ -115,7 +115,7 @@ GEGL_sources = \
gegl-types-internal.h \
gegl-xml.h
EXTRA_DIST = gegl-algorithms-boxfilter.inc
EXTRA_DIST = gegl-algorithms-boxfilter.inc gegl-algorithms-2x2-downscale.inc
lib_LTLIBRARIES = libgegl-@GEGL_API_VERSION@.la
......
......@@ -32,6 +32,7 @@
#include "gegl-tile-handler-zoom.h"
#include "gegl-tile-backend.h"
#include "gegl-tile-storage.h"
#include "gegl-algorithms.h"
G_DEFINE_TYPE (GeglTileHandlerZoom, gegl_tile_handler_zoom,
......@@ -59,181 +60,6 @@ static inline void set_blank (GeglTile *dst_tile,
}
}
/* fixme: make the api of this, as well as blank be the
* same as the downscale functions */
static inline void set_half_nearest (GeglTile *dst_tile,
GeglTile *src_tile,
gint width,
gint height,
const Babl *format,
gint i,
gint j)
{
guchar *dst_data = gegl_tile_get_data (dst_tile);
guchar *src_data = gegl_tile_get_data (src_tile);
gint bpp = babl_format_get_bytes_per_pixel (format);
gint x, y;
for (y = 0; y < height / 2; y++)
{
guchar *dst = dst_data +
(
(
(y + j * (height / 2)) * width
) + i * (width / 2)
) * bpp;
guchar *src = src_data + (y * 2 * width) * bpp;
for (x = 0; x < width / 2; x++)
{
memcpy (dst, src, bpp);
dst += bpp;
src += bpp * 2;
}
}
}
static inline void
downscale_float (gint components,
gint width,
gint height,
gint rowstride,
guchar *src_data,
guchar *dst_data)
{
gint y;
if (!src_data || !dst_data)
return;
for (y = 0; y < height / 2; y++)
{
gint x;
gfloat *dst = (gfloat *) (dst_data + y * rowstride);
gfloat *src = (gfloat *) (src_data + y * 2 * rowstride);
for (x = 0; x < width / 2; x++)
{
int i;
for (i = 0; i < components; i++)
dst[i] = (src[i] +
src[i + components] +
src[i + (width * components)] +
src[i + (width + 1) * components]) /
4.0;
dst += components;
src += components * 2;
}
}
}
static inline void
downscale_u32 (gint components,
gint width,
gint height,
gint rowstride,
guchar *src_data,
guchar *dst_data)
{
gint y;
if (!src_data || !dst_data)
return;
for (y = 0; y < height / 2; y++)
{
gint x;
guint32 *dst = (guint32 *) (dst_data + y * rowstride);
guint32 *src = (guint32 *) (src_data + y * 2 * rowstride);
for (x = 0; x < width / 2; x++)
{
int i;
for (i = 0; i < components; i++)
{
guint64 out = src[i];
out += src[i + components];
out += src[i + (width * components)];
out += src[i + (width + 1) * components];
out /= 4;
dst[i] = out;
}
dst += components;
src += components * 2;
}
}
}
static inline void
downscale_u16 (gint components,
gint width,
gint height,
gint rowstride,
guchar *src_data,
guchar *dst_data)
{
gint y;
if (!src_data || !dst_data)
return;
for (y = 0; y < height / 2; y++)
{
gint x;
guint16 *dst = (guint16 *) (dst_data + y * rowstride);
guint16 *src = (guint16 *) (src_data + y * 2 * rowstride);
for (x = 0; x < width / 2; x++)
{
int i;
for (i = 0; i < components; i++)
dst[i] = (src[i] +
src[i + components] +
src[i + (width * components)] +
src[i + (width + 1) * components]) /
4;
dst += components;
src += components * 2;
}
}
}
static inline void
downscale_u8 (gint components,
gint width,
gint height,
gint rowstride,
guchar *src_data,
guchar *dst_data)
{
gint y;
if (!src_data || !dst_data)
return;
for (y = 0; y < height / 2; y++)
{
gint x;
guchar *dst = dst_data + y * rowstride;
guchar *src = src_data + y * 2 * rowstride;
for (x = 0; x < width / 2; x++)
{
int i;
for (i = 0; i < components; i++)
dst[i] = (src[i] +
src[i + components] +
src[i + rowstride] +
src[i + rowstride + components]) /
4;
dst += components;
src += components * 2;
}
}
}
static inline void set_half (GeglTile * dst_tile,
GeglTile * src_tile,
gint width,
......@@ -244,33 +70,12 @@ static inline void set_half (GeglTile * dst_tile,
{
guchar *dst_data = gegl_tile_get_data (dst_tile);
guchar *src_data = gegl_tile_get_data (src_tile);
gint components = babl_format_get_n_components (format);
gint bpp = babl_format_get_bytes_per_pixel (format);
const Babl *comp_type = babl_format_get_type (format, 0);
if (i) dst_data += bpp * width / 2;
if (j) dst_data += bpp * width * height / 2;
if (comp_type == babl_type ("float"))
{
downscale_float (components, width, height, width * bpp, src_data, dst_data);
}
else if (comp_type == babl_type ("u8"))
{
downscale_u8 (components, width, height, width * bpp, src_data, dst_data);
}
else if (comp_type == babl_type ("u16"))
{
downscale_u16 (components, width, height, width * bpp, src_data, dst_data);
}
else if (comp_type == babl_type ("u32"))
{
downscale_u32 (components, width, height, width * bpp, src_data, dst_data);
}
else
{
set_half_nearest (dst_tile, src_tile, width, height, format, i, j);
}
gegl_downscale_2x2 (format, width, height, src_data, width * bpp, dst_data, width * bpp);
}
static GeglTile *
......
void
DOWNSCALE_FUNCNAME (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride)
{
gint y;
const gint components = bpp / sizeof(DOWNSCALE_TYPE);
if (!src_data || !dst_data)
return;
for (y = 0; y < src_height / 2; y++)
{
gint x;
guchar *src = src_data;
guchar *dst = dst_data;
for (x = 0; x < src_width / 2; x++)
{
gint i;
for (i = 0; i < components; i++)
{
DOWNSCALE_SUM aa = ((DOWNSCALE_TYPE *)(src))[i];
DOWNSCALE_SUM ab = ((DOWNSCALE_TYPE *)(src + bpp))[i];
DOWNSCALE_SUM ba = ((DOWNSCALE_TYPE *)(src + src_rowstride))[i];
DOWNSCALE_SUM bb = ((DOWNSCALE_TYPE *)(src + src_rowstride + bpp))[i];
((DOWNSCALE_TYPE *)dst)[i] = (aa + ab + ba + bb) / DOWNSCALE_DIVISOR;
}
dst += bpp;
src += bpp * 2;
}
dst_data += dst_rowstride;
src_data += 2 * src_rowstride;
}
}
\ No newline at end of file
......@@ -30,6 +30,58 @@
#include <math.h>
void gegl_downscale_2x2 (const Babl *format,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride)
{
const gint bpp = babl_format_get_bytes_per_pixel (format);
const Babl *comp_type = babl_format_get_type (format, 0);
if (comp_type == babl_type ("float"))
gegl_downscale_2x2_float (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
else if (comp_type == babl_type ("u8"))
gegl_downscale_2x2_u8 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
else if (comp_type == babl_type ("u16"))
gegl_downscale_2x2_u16 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
else if (comp_type == babl_type ("u32"))
gegl_downscale_2x2_u32 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
else
gegl_downscale_2x2_nearest (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
}
void
gegl_downscale_2x2_nearest (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride)
{
gint y;
for (y = 0; y < src_height / 2; y++)
{
gint x;
guchar *src = src_data;
guchar *dst = dst_data;
for (x = 0; x < src_width / 2; x++)
{
memcpy (dst, src, bpp);
dst += bpp;
src += bpp * 2;
}
dst_data += dst_rowstride;
src_data += src_rowstride * 2;
}
}
void gegl_resample_boxfilter (guchar *dest_buf,
const guchar *source_buf,
const GeglRectangle *dst_rect,
......@@ -161,4 +213,56 @@ gegl_resample_nearest (guchar *dst,
#include "gegl-algorithms-boxfilter.inc"
#undef BOXFILTER_FUNCNAME
#undef BOXFILTER_TYPE
#undef BOXFILTER_ROUND
\ No newline at end of file
#undef BOXFILTER_ROUND
/*
#define DOWNSCALE_FUNCNAME gegl_downscale_2x2_double
#define DOWNSCALE_TYPE gdouble
#define DOWNSCALE_SUM gdouble
#define DOWNSCALE_DIVISOR 4.0
#include "gegl-algorithms-2x2-downscale.inc"
#undef DOWNSCALE_FUNCNAME
#undef DOWNSCALE_TYPE
#undef DOWNSCALE_SUM
#undef DOWNSCALE_DIVISOR
*/
#define DOWNSCALE_FUNCNAME gegl_downscale_2x2_float
#define DOWNSCALE_TYPE gfloat
#define DOWNSCALE_SUM gfloat
#define DOWNSCALE_DIVISOR 4.0f
#include "gegl-algorithms-2x2-downscale.inc"
#undef DOWNSCALE_FUNCNAME
#undef DOWNSCALE_TYPE
#undef DOWNSCALE_SUM
#undef DOWNSCALE_DIVISOR
#define DOWNSCALE_FUNCNAME gegl_downscale_2x2_u32
#define DOWNSCALE_TYPE guint32
#define DOWNSCALE_SUM guint64
#define DOWNSCALE_DIVISOR 4
#include "gegl-algorithms-2x2-downscale.inc"
#undef DOWNSCALE_FUNCNAME
#undef DOWNSCALE_TYPE
#undef DOWNSCALE_SUM
#undef DOWNSCALE_DIVISOR
#define DOWNSCALE_FUNCNAME gegl_downscale_2x2_u16
#define DOWNSCALE_TYPE guint16
#define DOWNSCALE_SUM guint
#define DOWNSCALE_DIVISOR 4
#include "gegl-algorithms-2x2-downscale.inc"
#undef DOWNSCALE_FUNCNAME
#undef DOWNSCALE_TYPE
#undef DOWNSCALE_SUM
#undef DOWNSCALE_DIVISOR
#define DOWNSCALE_FUNCNAME gegl_downscale_2x2_u8
#define DOWNSCALE_TYPE guint8
#define DOWNSCALE_SUM guint
#define DOWNSCALE_DIVISOR 4
#include "gegl-algorithms-2x2-downscale.inc"
#undef DOWNSCALE_FUNCNAME
#undef DOWNSCALE_TYPE
#undef DOWNSCALE_SUM
#undef DOWNSCALE_DIVISOR
......@@ -23,6 +23,54 @@ G_BEGIN_DECLS
#define GEGL_SCALE_EPSILON 1.e-6
void gegl_downscale_2x2 (const Babl *format,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride);
void gegl_downscale_2x2_float (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride);
void gegl_downscale_2x2_u32 (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride);
void gegl_downscale_2x2_u16 (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride);
void gegl_downscale_2x2_u8 (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride);
void gegl_downscale_2x2_nearest (gint bpp,
gint src_width,
gint src_height,
guchar *src_data,
gint src_rowstride,
guchar *dst_data,
gint dst_rowstride);
/* Attempt to resample with a 3x3 boxfilter, if no boxfilter is
* available for #format fall back to nearest neighbor.
* #scale is assumed to be between 0.5 and +inf.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment