gimp r26896 - in trunk: . app app/paint-funcs
- From: neo svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r26896 - in trunk: . app app/paint-funcs
- Date: Sun, 7 Sep 2008 21:13:09 +0000 (UTC)
Author: neo
Date: Sun Sep 7 21:13:09 2008
New Revision: 26896
URL: http://svn.gnome.org/viewvc/gimp?rev=26896&view=rev
Log:
2008-09-07 Sven Neumann <sven gimp org>
Applied 'gimp-decimate.diff' as announced on the mailing-list:
* app/gimp-log.[ch]: added log domain "scale".
* app/paint-funcs/scale-region.c: replaced decimation routines
with box filters. Only use the decimation routines to pre-scale
the image, always apply the interpolation for the final step.
Modified:
trunk/ChangeLog
trunk/app/gimp-log.c
trunk/app/gimp-log.h
trunk/app/paint-funcs/scale-region.c
Modified: trunk/app/gimp-log.c
==============================================================================
--- trunk/app/gimp-log.c (original)
+++ trunk/app/gimp-log.c Sun Sep 7 21:13:09 2008
@@ -43,7 +43,8 @@
{ "menus", GIMP_LOG_MENUS },
{ "save-dialog", GIMP_LOG_SAVE_DIALOG },
{ "image-scale", GIMP_LOG_IMAGE_SCALE },
- { "shadow-tiles", GIMP_LOG_SHADOW_TILES }
+ { "shadow-tiles", GIMP_LOG_SHADOW_TILES },
+ { "scale", GIMP_LOG_SCALE }
};
gimp_log_flags = g_parse_debug_string (env_log_val,
Modified: trunk/app/gimp-log.h
==============================================================================
--- trunk/app/gimp-log.h (original)
+++ trunk/app/gimp-log.h Sun Sep 7 21:13:09 2008
@@ -30,7 +30,8 @@
GIMP_LOG_MENUS = 1 << 5,
GIMP_LOG_SAVE_DIALOG = 1 << 6,
GIMP_LOG_IMAGE_SCALE = 1 << 7,
- GIMP_LOG_SHADOW_TILES = 1 << 8
+ GIMP_LOG_SHADOW_TILES = 1 << 8,
+ GIMP_LOG_SCALE = 1 << 9
} GimpLogFlags;
@@ -80,6 +81,7 @@
#define SAVE_DIALOG GIMP_LOG_SAVE_DIALOG
#define IMAGE_SCALE GIMP_LOG_IMAGE_SCALE
#define SHADOW_TILES GIMP_LOG_SHADOW_TILES
+#define SCALE GIMP_LOG_SCALE
#if 0 /* last resort */
# define GIMP_LOG /* nothing => no varargs, no log */
Modified: trunk/app/paint-funcs/scale-region.c
==============================================================================
--- trunk/app/paint-funcs/scale-region.c (original)
+++ trunk/app/paint-funcs/scale-region.c Sun Sep 7 21:13:09 2008
@@ -34,6 +34,8 @@
#include "paint-funcs.h"
#include "scale-region.h"
+#include "gimp-log.h"
+
#define NUM_TILES(w,h) ((((w) + (TILE_WIDTH - 1)) / TILE_WIDTH) * \
(((h) + (TILE_HEIGHT - 1)) / TILE_HEIGHT))
@@ -62,34 +64,60 @@
gpointer progress_data,
gint *progress,
gint max_progress);
-static void interpolate_nearest (TileManager *srcTM,
+static void decimate_xy (TileManager *srcTM,
+ TileManager *dstTM,
+ GimpInterpolationType interpolation,
+ GimpProgressFunc progress_callback,
+ gpointer progress_data,
+ gint *progress,
+ gint max_progress);
+static void decimate_x (TileManager *srcTM,
+ TileManager *dstTM,
+ GimpInterpolationType interpolation,
+ GimpProgressFunc progress_callback,
+ gpointer progress_data,
+ gint *progress,
+ gint max_progress);
+static void decimate_y (TileManager *srcTM,
+ TileManager *dstTM,
+ GimpInterpolationType interpolation,
+ GimpProgressFunc progress_callback,
+ gpointer progress_data,
+ gint *progress,
+ gint max_progress);
+static void decimate_average_xy (PixelSurround *surround,
const gint x0,
const gint y0,
- const gdouble xfrac,
- const gdouble yfrac,
+ const gint bytes,
guchar *pixel);
-static void interpolate_bilinear (PixelSurround *surround,
+static void decimate_average_y (PixelSurround *surround,
const gint x0,
const gint y0,
- const gdouble xfrac,
- const gdouble yfrac,
const gint bytes,
guchar *pixel);
-static void interpolate_cubic (PixelSurround *surround,
+static void decimate_average_x (PixelSurround *surround,
+ const gint x0,
+ const gint y0,
+ const gint bytes,
+ guchar *pixel);
+static void interpolate_nearest (TileManager *srcTM,
const gint x0,
const gint y0,
const gdouble xfrac,
const gdouble yfrac,
- const gint bytes,
guchar *pixel);
-static void decimate_gauss (PixelSurround *surround,
+static void interpolate_bilinear (PixelSurround *surround,
const gint x0,
const gint y0,
+ const gdouble xfrac,
+ const gdouble yfrac,
const gint bytes,
guchar *pixel);
-static void decimate_average (PixelSurround *surround,
+static void interpolate_cubic (PixelSurround *surround,
const gint x0,
const gint y0,
+ const gdouble xfrac,
+ const gdouble yfrac,
const gint bytes,
guchar *pixel);
static gfloat * create_lanczos3_lookup (void);
@@ -109,29 +137,6 @@
const gdouble xfrac,
const gdouble yfrac,
guchar *pixel);
-static inline void gaussian_lanczos2 (const guchar *src,
- const gint x,
- const gint y,
- const gint bytes,
- const gint stride,
- guchar *pixel);
-static inline void decimate_lanczos2 (PixelSurround *surround,
- const gint x0,
- const gint y0,
- const gint bytes,
- guchar *pixel);
-static inline void pixel_average (const guchar *p1,
- const guchar *p2,
- const guchar *p3,
- const guchar *p4,
- guchar *pixel,
- const gint bytes);
-static inline void gaussian_decimate (const guchar *src,
- const gint x,
- const gint y,
- const gint bytes,
- const gint stride,
- guchar *pixel);
static inline gdouble cubic_spline_fit (const gdouble dx,
const gdouble x1,
const gdouble y1,
@@ -223,14 +228,14 @@
*levely -= 1;
}
- while (scalex < 0.5)
+ while (scalex < 0.5 && width > 1)
{
scalex *= 2;
width /= 2;
*levelx += 1;
}
- while (scaley < 0.5)
+ while (scaley < 0.5 && height > 1)
{
scaley *= 2;
height *= 2;
@@ -330,7 +335,11 @@
gint levely = 0;
/* determine scaling levels */
- scale_determine_levels (srcPR, dstPR, &levelx, &levely);
+ if (interpolation != GIMP_INTERPOLATION_NONE)
+ {
+ scale_determine_levels (srcPR, dstPR, &levelx, &levely);
+ }
+
max_progress = scale_determine_progress (srcPR, dstPR, levelx, levely);
if (levelx == 0 && levely == 0)
@@ -392,8 +401,8 @@
height >>= 1;
tmpTM = tile_manager_new (width, height, bytes);
- scale (srcTM, tmpTM, interpolation,
- progress_callback, progress_data, &progress, max_progress);
+ decimate_xy (srcTM, tmpTM, interpolation,
+ progress_callback, progress_data, &progress, max_progress);
if (srcTM != srcPR->tiles)
tile_manager_unref (srcTM);
@@ -408,8 +417,8 @@
width >>= 1;
tmpTM = tile_manager_new (width, height, bytes);
- scale (srcTM, tmpTM, interpolation,
- progress_callback, progress_data, &progress, max_progress);
+ decimate_x (srcTM, tmpTM, interpolation,
+ progress_callback, progress_data, &progress, max_progress);
if (srcTM != srcPR->tiles)
tile_manager_unref (srcTM);
@@ -423,8 +432,8 @@
height >>= 1;
tmpTM = tile_manager_new (width, height, bytes);
- scale (srcTM, tmpTM, interpolation,
- progress_callback, progress_data, &progress, max_progress);
+ decimate_y (srcTM, tmpTM, interpolation,
+ progress_callback, progress_data, &progress, max_progress);
if (srcTM != srcPR->tiles)
tile_manager_unref (srcTM);
@@ -459,16 +468,17 @@
PixelSurround *surround = NULL;
const guint src_width = tile_manager_width (srcTM);
const guint src_height = tile_manager_height (srcTM);
- const guint bytes = tile_manager_bpp (srcTM);
+ const guint bytes = tile_manager_bpp (dstTM);
const guint dst_width = tile_manager_width (dstTM);
const guint dst_height = tile_manager_height (dstTM);
const gdouble scaley = (gdouble) dst_height / (gdouble) src_height;
const gdouble scalex = (gdouble) dst_width / (gdouble) src_width;
- const gboolean decimate = (src_width == 2 * dst_width ||
- src_height == 2 * dst_height);
gpointer pr;
gfloat *kernel_lookup = NULL;
+ GIMP_LOG (SCALE, "scale: %dx%d -> %dx%d",
+ src_width, src_height, dst_width, dst_height);
+
/* fall back if not enough pixels available */
if (interpolation != GIMP_INTERPOLATION_NONE)
{
@@ -537,28 +547,19 @@
break;
case GIMP_INTERPOLATION_LINEAR:
- if (decimate)
- decimate_average (surround, sx0, sy0, bytes, pixel);
- else
- interpolate_bilinear (surround,
- sx0, sy0, xfrac, yfrac, bytes, pixel);
+ interpolate_bilinear (surround,
+ sx0, sy0, xfrac, yfrac, bytes, pixel);
break;
case GIMP_INTERPOLATION_CUBIC:
- if (decimate)
- decimate_gauss (surround, sx0, sy0, bytes, pixel);
- else
- interpolate_cubic (surround,
- sx0, sy0, xfrac, yfrac, bytes, pixel);
+ interpolate_cubic (surround,
+ sx0, sy0, xfrac, yfrac, bytes, pixel);
break;
case GIMP_INTERPOLATION_LANCZOS:
- if (decimate)
- decimate_lanczos2 (surround, sx0, sy0, bytes, pixel);
- else
- interpolate_lanczos3 (surround,
- sx0, sy0, xfrac, yfrac, bytes, pixel,
- kernel_lookup);
+ interpolate_lanczos3 (surround,
+ sx0, sy0, xfrac, yfrac, bytes, pixel,
+ kernel_lookup);
break;
}
@@ -584,13 +585,195 @@
pixel_surround_destroy (surround);
}
+static void
+decimate_xy (TileManager *srcTM,
+ TileManager *dstTM,
+ GimpInterpolationType interpolation,
+ GimpProgressFunc progress_callback,
+ gpointer progress_data,
+ gint *progress,
+ gint max_progress)
+{
+ PixelRegion region;
+ PixelSurround *surround = NULL;
+ const guint bytes = tile_manager_bpp (dstTM);
+ const guint dst_width = tile_manager_width (dstTM);
+ const guint dst_height = tile_manager_height (dstTM);
+ gpointer pr;
+
+ GIMP_LOG (SCALE, "decimate_xy: %dx%d -> %dx%d\n",
+ tile_manager_width (srcTM), tile_manager_height (srcTM),
+ dst_width, dst_height);
+
+ surround = pixel_surround_new (srcTM, 2, 2, PIXEL_SURROUND_SMEAR);
+
+ pixel_region_init (®ion, dstTM, 0, 0, dst_width, dst_height, TRUE);
+
+ for (pr = pixel_regions_register (1, ®ion);
+ pr != NULL;
+ pr = pixel_regions_process (pr))
+ {
+ const gint x1 = region.x + region.w;
+ const gint y1 = region.y + region.h;
+ guchar *row = region.data;
+ gint y;
+
+ for (y = region.y; y < y1; y++)
+ {
+ const gint sy = y * 2;
+ guchar *pixel = row;
+ gint x;
+
+ for (x = region.x; x < x1; x++)
+ {
+ decimate_average_xy (surround, x * 2, sy, bytes, pixel);
+
+ pixel += region.bytes;
+ }
+
+ row += region.rowstride;
+ }
+
+ if (progress_callback)
+ {
+ (*progress)++;
+
+ if (*progress % 16 == 0)
+ progress_callback (0, max_progress, *progress, progress_data);
+ }
+ }
+
+ pixel_surround_destroy (surround);
+}
+
+static void
+decimate_x (TileManager *srcTM,
+ TileManager *dstTM,
+ GimpInterpolationType interpolation,
+ GimpProgressFunc progress_callback,
+ gpointer progress_data,
+ gint *progress,
+ gint max_progress)
+{
+ PixelRegion region;
+ PixelSurround *surround = NULL;
+ const guint bytes = tile_manager_bpp (dstTM);
+ const guint dst_width = tile_manager_width (dstTM);
+ const guint dst_height = tile_manager_height (dstTM);
+ gpointer pr;
+
+ GIMP_LOG (SCALE, "decimate_x: %dx%d -> %dx%d\n",
+ tile_manager_width (srcTM), tile_manager_height (srcTM),
+ dst_width, dst_height);
+
+ surround = pixel_surround_new (srcTM, 2, 1, PIXEL_SURROUND_SMEAR);
+
+ pixel_region_init (®ion, dstTM, 0, 0, dst_width, dst_height, TRUE);
+
+ for (pr = pixel_regions_register (1, ®ion);
+ pr != NULL;
+ pr = pixel_regions_process (pr))
+ {
+ const gint x1 = region.x + region.w;
+ const gint y1 = region.y + region.h;
+ guchar *row = region.data;
+ gint y;
+
+ for (y = region.y; y < y1; y++)
+ {
+ guchar *pixel = row;
+ gint x;
+
+ for (x = region.x; x < x1; x++)
+ {
+ decimate_average_x (surround, x * 2, y, bytes, pixel);
+
+ pixel += region.bytes;
+ }
+
+ row += region.rowstride;
+ }
+
+ if (progress_callback)
+ {
+ (*progress)++;
+
+ if (*progress % 32 == 0)
+ progress_callback (0, max_progress, *progress, progress_data);
+ }
+ }
+
+ pixel_surround_destroy (surround);
+}
+
+static void
+decimate_y (TileManager *srcTM,
+ TileManager *dstTM,
+ GimpInterpolationType interpolation,
+ GimpProgressFunc progress_callback,
+ gpointer progress_data,
+ gint *progress,
+ gint max_progress)
+{
+ PixelRegion region;
+ PixelSurround *surround = NULL;
+ const guint bytes = tile_manager_bpp (dstTM);
+ const guint dst_width = tile_manager_width (dstTM);
+ const guint dst_height = tile_manager_height (dstTM);
+ gpointer pr;
+
+ GIMP_LOG (SCALE, "decimate_y: %dx%d -> %dx%d\n",
+ tile_manager_width (srcTM), tile_manager_height (srcTM),
+ dst_width, dst_height);
+
+ surround = pixel_surround_new (srcTM, 1, 2, PIXEL_SURROUND_SMEAR);
+
+ pixel_region_init (®ion, dstTM, 0, 0, dst_width, dst_height, TRUE);
+
+ for (pr = pixel_regions_register (1, ®ion);
+ pr != NULL;
+ pr = pixel_regions_process (pr))
+ {
+ const gint x1 = region.x + region.w;
+ const gint y1 = region.y + region.h;
+ guchar *row = region.data;
+ gint y;
+
+ for (y = region.y; y < y1; y++)
+ {
+ const gint sy = y * 2;
+ guchar *pixel = row;
+ gint x;
+
+ for (x = region.x; x < x1; x++)
+ {
+ decimate_average_y (surround, x, sy, bytes, pixel);
+
+ pixel += region.bytes;
+ }
+
+ row += region.rowstride;
+ }
+
+ if (progress_callback)
+ {
+ (*progress)++;
+
+ if (*progress % 32 == 0)
+ progress_callback (0, max_progress, *progress, progress_data);
+ }
+ }
+
+ pixel_surround_destroy (surround);
+}
+
static void inline
-pixel_average (const guchar *p1,
- const guchar *p2,
- const guchar *p3,
- const guchar *p4,
- guchar *p,
- const gint bytes)
+pixel_average4 (const guchar *p1,
+ const guchar *p2,
+ const guchar *p3,
+ const guchar *p4,
+ guchar *p,
+ const gint bytes)
{
switch (bytes)
{
@@ -668,276 +851,118 @@
}
}
-static void
-decimate_gauss (PixelSurround *surround,
- const gint x0,
- const gint y0,
- const gint bytes,
- guchar *pixel)
+static void inline
+pixel_average2 (const guchar *p1,
+ const guchar *p2,
+ guchar *p,
+ const gint bytes)
{
- gint stride;
- const guchar *src = pixel_surround_lock (surround, x0 - 1, y0 - 1, &stride);
- guchar pixel1[4];
- guchar pixel2[4];
- guchar pixel3[4];
- guchar pixel4[4];
-
- gaussian_decimate (src, 0, 0, bytes, stride, pixel1);
- gaussian_decimate (src, 1, 0, bytes, stride, pixel2);
- gaussian_decimate (src, 0, 1, bytes, stride, pixel3);
- gaussian_decimate (src, 1, 1, bytes, stride, pixel4);
-
- pixel_average (pixel1, pixel2, pixel3, pixel4, pixel, bytes);
-}
-
-static inline void
-gaussian_decimate (const guchar *src,
- const gint x,
- const gint y,
- const gint bytes,
- const gint stride,
- guchar *pixel)
-{
- const guchar *s0 = src + x * bytes + y * stride;
- const guchar *s1 = s0 + stride;
- const guchar *s2 = s1 + stride;
- guint sum;
- guint alphasum;
- gint b;
-
switch (bytes)
{
case 1:
- sum = (s0[0] + s0[1] * 2 + s0[2] +
- s1[0] * 2 + s1[1] * 4 + s1[2] * 2 +
- s2[0] + s2[1] * 2 + s2[2]);
-
- pixel[0] = (sum + 8) >> 4;
+ p[0] = (p1[0] + p2[0] + 1) >> 1;
break;
case 2:
- alphasum = (s0[1] + s0[3] * 2 + s0[5] +
- s1[1] * 2 + s1[3] * 4 + s1[5] * 2 +
- s2[1] + s2[3] * 2 + s2[5]);
+ {
+ guint a = p1[1] + p2[1];
- if (alphasum > 0)
- {
- sum = (s0[0] * s0[1] + s0[2] * s0[3] * 2 + s0[4] * s0[5] +
- s1[0] * s1[1] * 2 + s1[2] * s1[3] * 4 + s1[4] * s1[5] * 2 +
- s2[0] * s2[1] + s2[2] * s2[3] * 2 + s2[4] * s2[5]);
+ switch (a)
+ {
+ case 0: /* all transparent */
+ p[0] = p[1] = 0;
+ break;
- pixel[0] = (sum + (alphasum >> 1)) / alphasum;
- pixel[1] = (alphasum + 8) >> 4;
- }
- else
- {
- pixel[0] = pixel[1] = 0;
- }
+ case 510: /* all opaque */
+ p[0] = (p1[0] + p2[0] + 1) >> 2;
+ p[1] = 255;
+ break;
+
+ default:
+ p[0] = ((p1[0] * p1[1] +
+ p2[0] * p2[1] + (a >> 1)) / a);
+ p[1] = (a + 1) >> 1;
+ break;
+ }
+ }
break;
case 3:
- for (b = 0; b < 3; b++ )
- {
- sum = (s0[b] + s0[3 + b] * 2 + s0[6 + b] +
- s1[b] * 2 + s1[3 + b] * 4 + s1[6 + b] * 2 +
- s2[b] + s2[3 + b] * 2 + s2[6 + b]);
-
- pixel[b] = (sum + 8) >> 4;
- }
+ p[0] = (p1[0] + p2[0] + 1) >> 1;
+ p[1] = (p1[1] + p2[1] + 1) >> 1;
+ p[2] = (p1[2] + p2[2] + 1) >> 1;
break;
case 4:
- alphasum = (s0[3] + s0[7] * 2 + s0[11] +
- s1[3] * 2 + s1[7] * 4 + s1[11] * 2 +
- s2[3] + s2[7] * 2 + s2[11]);
+ {
+ guint a = p1[3] + p2[3];
- if (alphasum > 0)
- {
- for (b = 0; b < 3; b++)
- {
- sum = (s0[b] * s0[3] + s0[4 + b] * s0[7] * 2 + s0[8 + b] * s0[11] +
- s1[b] * s1[3] * 2 + s1[4 + b] * s1[7] * 4 + s1[8 + b] * s1[11] * 2 +
- s2[b] * s2[3] + s2[4 + b] * s2[7] * 2 + s2[8 + b] * s2[11]);
+ switch (a)
+ {
+ case 0: /* all transparent */
+ p[0] = p[1] = p[2] = p[3] = 0;
+ break;
- pixel[b] = (sum + (alphasum >> 1)) / alphasum;
- }
+ case 510: /* all opaque */
+ p[0] = (p1[0] + p2[0] + 1) >> 1;
+ p[1] = (p1[1] + p2[1] + 1) >> 1;
+ p[2] = (p1[2] + p2[2] + 1) >> 1;
+ p[3] = 255;
+ break;
- pixel[3] = (alphasum + 8) >> 4;
- }
- else
- {
- pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0;
- }
+ default:
+ p[0] = ((p1[0] * p1[3] +
+ p2[0] * p2[3] + (a >> 1)) / a);
+ p[1] = ((p1[1] * p1[3] +
+ p2[1] * p2[3] + (a >> 1)) / a);
+ p[2] = ((p1[2] * p1[3] +
+ p2[2] * p2[3] + (a >> 1)) / a);
+ p[3] = (a + 1) >> 1;
+ break;
+ }
+ }
break;
}
}
-static inline void
-decimate_lanczos2 (PixelSurround *surround,
- const gint x0,
- const gint y0,
- const gint bytes,
- guchar *pixel)
+static void
+decimate_average_xy (PixelSurround *surround,
+ const gint x0,
+ const gint y0,
+ const gint bytes,
+ guchar *pixel)
{
gint stride;
- const guchar *src = pixel_surround_lock (surround, x0 - 2, y0 - 2, &stride);
- guchar pixel1[4];
- guchar pixel2[4];
- guchar pixel3[4];
- guchar pixel4[4];
-
- gaussian_lanczos2 (src, 0, 0, bytes, stride, pixel1);
- gaussian_lanczos2 (src, 1, 0, bytes, stride, pixel2);
- gaussian_lanczos2 (src, 0, 1, bytes, stride, pixel3);
- gaussian_lanczos2 (src, 1, 1, bytes, stride, pixel4);
-
- pixel_average (pixel1, pixel2, pixel3, pixel4, pixel, bytes);
-}
-
-static inline void
-gaussian_lanczos2 (const guchar *src,
- const gint x,
- const gint y,
- const gint bytes,
- const gint stride,
- guchar *pixel)
-{
- /*
- * Filter source taken from document:
- * www.worldserver.com/turk/computergraphics/ResamplingFilters.pdf
- *
- * Filters for Common Resampling Tasks
- *
- * Ken Turkowski, Apple computer
- *
- */
- const guchar *s0 = src + x * bytes + y * stride;
- const guchar *s1 = s0 + stride;
- const guchar *s2 = s1 + stride;
- const guchar *s3 = s2 + stride;
- const guchar *s4 = s3 + stride;
- gdouble sum;
- gdouble alphasum;
- gdouble alpha;
- gint b;
-
- switch (bytes)
- {
- case 1:
- sum = s0[0] + s0[1] * -9 + s0[2] * -16 + s0[3] * -9 + s0[4];
- sum += s1[0] * -9 + s1[1] * 81 + s1[2] * 144 + s1[3] * 81 + s1[4] * -9;
- sum += s2[0] * -16 + s2[1] * 144 + s2[2] * 256 + s2[3] * 144 + s2[4] * -16;
- sum += s3[0] * -9 + s3[1] * 81 + s3[2] * 144 + s3[3] * 81 + s3[4] * -9;
- sum += s4[0] + s4[1] * -9 + s4[2] * -16 + s4[3] * -9 + s4[4];
-
- sum /= 1024;
-
- pixel[0] = CLAMP (sum, 0, 255);
- break;
-
- case 2:
- alphasum = s0[1] + s0[3] * -9 + s0[5] * -16 + s0[7] * -9 + s0[9];
- alphasum += s1[1] * -9 + s1[3] * 81 + s1[5] * 144 + s1[7] * 81 + s1[9] * -9;
- alphasum += s2[1] * -16 + s2[3] * 144 + s2[5] * 256 + s2[7] * 144 + s2[9] * -16;
- alphasum += s3[1] * -9 + s3[3] * 81 + s3[5] * 144 + s3[7] * 81 + s3[9] * -9;
- alphasum += s4[1] + s4[3] * -9 + s4[5] * -16 + s4[7] * -9 + s4[9];
-
- if (alphasum > 0)
- {
- sum = (s0[0] * s0[1] + s0[2] * s0[3] * -9 +
- s0[4] * s0[5] * -16 + s0[6] * s0[7] * -9 + s0[8] * s0[9]);
- sum += (s1[0] * s1[1] * -9 + s1[2] * s1[3] * 81 +
- s1[4] * s1[5] * 144 + s1[6] * s1[7] * 81 + s1[8] * s1[9] * -9);
- sum += (s2[0] * s2[1] * -16 + s2[2] * s2[3] * 144 +
- s2[4] * s2[5] * 256 + s2[6] * s2[7] * 144 + s2[8] * s2[9] * -16);
- sum += (s3[0] * s3[1] * -9 + s3[2] * s3[3] * 81 +
- s3[4] * s3[5] * 144 + s3[6] * s3[7] * 81 + s3[8] * s3[9] * -9);
- sum += (s4[0] * s4[1] + s4[2] * s4[3] * -9 +
- s4[4] * s4[5] * -16 + s4[6] * s4[7] * -9 + s4[8] * s4[9]);
-
- sum /= alphasum;
- alpha = alphasum / 1024;
-
- pixel[0] = CLAMP (sum, 0, 255);
- pixel[1] = CLAMP (alpha, 0, 255);
- }
- else
- {
- pixel[0] = pixel[1] = 0;
- }
- break;
-
- case 3:
- for (b = 0; b < 3; b++)
- {
- sum = s0[b] + s0[3 + b] * -9 + s0[6 + b] * -16 + s0[9 + b] * -9 + s0[12 + b];
- sum += s1[b] * -9 + s1[3 + b] * 81 + s1[6 + b] * 144 + s1[9 + b] * 81 + s1[12 + b] * -9;
- sum += s2[b] * -16 + s2[3 + b] * 144 + s2[6 + b] * 256 + s2[9 + b] * 144 + s2[12 + b] * -16;
- sum += s3[b] * -9 + s3[3 + b] * 81 + s3[6 + b] * 144 + s3[9 + b] * 81 + s3[12 + b] * -9;
- sum += s4[b] + s4[3 + b] * -9 + s4[6 + b] * -16 + s4[9 + b] * -9 + s4[12 + b];
-
- sum /= 1024;
-
- pixel[b] = CLAMP (sum, 0, 255);
- }
- break;
-
- case 4:
- alphasum = s0[3] + s0[7] * -9 + s0[11] * -16 + s0[15] * -9 + s0[19];
- alphasum += s1[3] * -9 + s1[7] * 81 + s1[11] * 144 + s1[15] * 81 + s1[19] * -9;
- alphasum += s2[3] * -16 + s2[7] * 144 + s2[11] * 256 + s2[15] * 144 + s2[19] * -16;
- alphasum += s3[3] * -9 + s3[7] * 81 + s3[11] * 144 + s3[15] * 81 + s3[19] * -9;
- alphasum += s4[3] + s4[7] * -9 + s4[11] * -16 + s4[15] * -9 + s4[19];
-
- if (alphasum > 0)
- {
- for (b = 0; b < 3; b++)
- {
- sum = (s0[0 + b] * s0[3] + s0[ 4 + b] * s0[ 7] * -9 +
- s0[8 + b] * s0[11] * -16 + s0[12 + b] * s0[15] * -9 +
- s0[16 + b] * s0[19]);
- sum += (s1[0 + b] * s1[3] * -9 + s1[ 4 + b] * s1[ 7] * 81 +
- s1[8 + b] * s1[11] * 144 + s1[12 + b] * s1[15] * 81 +
- s1[16 + b] * s1[19] * -9);
- sum += (s2[0 + b] * s2[3] * -16 + s2[ 4 + b] * s2[ 7] * 144 +
- s2[8 + b] * s2[11] * 256 + s2[12 + b] * s2[15] * 144 +
- s2[16 + b] * s2[19] * -16);
- sum += (s3[0 + b] * s3[3] * -9 + s3[ 4 + b] * s3[ 7] * 81 +
- s3[8 + b] * s3[11] * 144 + s3[12 + b] * s3[15] * 81 +
- s3[16 + b] * s3[19] * -9);
- sum += (s4[0 + b] * s4[3] + s4[ 4 + b] * s4[7] * -9 +
- s4[8 + b] * s4[11] * -16 + s4[12 + b] * s4[15] * -9 +
- s4[16 + b] * s4[19]);
-
- sum /= alphasum;
+ const guchar *src = pixel_surround_lock (surround, x0, y0, &stride);
- pixel[b] = CLAMP (sum, 0, 255);
- }
+ pixel_average4 (src, src + bytes, src + stride, src + stride + bytes,
+ pixel, bytes);
+}
- alpha = alphasum / 1024;
+static void
+decimate_average_x (PixelSurround *surround,
+ const gint x0,
+ const gint y0,
+ const gint bytes,
+ guchar *pixel)
+{
+ gint stride;
+ const guchar *src = pixel_surround_lock (surround, x0, y0, &stride);
- pixel[3] = CLAMP (alpha, 0, 255);
- }
- else
- {
- pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0;
- }
- break;
- }
+ pixel_average2 (src, src + bytes, pixel, bytes);
}
static void
-decimate_average (PixelSurround *surround,
- const gint x0,
- const gint y0,
- const gint bytes,
- guchar *pixel)
+decimate_average_y (PixelSurround *surround,
+ const gint x0,
+ const gint y0,
+ const gint bytes,
+ guchar *pixel)
{
gint stride;
const guchar *src = pixel_surround_lock (surround, x0, y0, &stride);
- pixel_average (src, src + bytes, src + stride, src + stride + bytes,
- pixel, bytes);
+ pixel_average2 (src, src + stride, pixel, bytes);
}
static inline gdouble
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]