mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-20 19:43:01 +00:00
app: remove paint-funcs/reduce-region.[ch]
This commit is contained in:
parent
23811be3f6
commit
8e31fdf363
|
@ -25,7 +25,5 @@ libapppaint_funcs_a_SOURCES = \
|
|||
paint-funcs-generic.h \
|
||||
paint-funcs-types.h \
|
||||
paint-funcs-utils.h \
|
||||
reduce-region.c \
|
||||
reduce-region.h \
|
||||
subsample-region.c \
|
||||
subsample-region.h
|
||||
|
|
|
@ -1,389 +0,0 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
|
||||
#include "paint-funcs-types.h"
|
||||
|
||||
#include "base/pixel-region.h"
|
||||
|
||||
#include "paint-funcs.h"
|
||||
#include "reduce-region.h"
|
||||
|
||||
|
||||
static void reduce_pixel_region (PixelRegion *srcPR,
|
||||
guchar *dst,
|
||||
gint bytes);
|
||||
static void reduce_buffer (const guchar *src,
|
||||
guchar *dst,
|
||||
gint bytes,
|
||||
gint width,
|
||||
gint height,
|
||||
gint alpha);
|
||||
static void reduce_row (const guchar *src,
|
||||
guchar *dst,
|
||||
gint width,
|
||||
gint bytes,
|
||||
gint alpha);
|
||||
static void reduce_bilinear_pr (PixelRegion *dstPR,
|
||||
PixelRegion *srcPR);
|
||||
static void reduce_bilinear (PixelRegion *dstPR,
|
||||
const guchar *src,
|
||||
gint source_w,
|
||||
gint source_h,
|
||||
gint bytes);
|
||||
|
||||
|
||||
void
|
||||
reduce_region (PixelRegion *srcPR,
|
||||
PixelRegion *dstPR,
|
||||
GimpProgressFunc progress_callback,
|
||||
gpointer progress_data)
|
||||
{
|
||||
const gint bytes = dstPR->bytes;
|
||||
gint alpha = 0;
|
||||
gint level = 0;
|
||||
gdouble scale = (gdouble) dstPR->h / (gdouble) srcPR->h;
|
||||
|
||||
if (pixel_region_has_alpha (srcPR))
|
||||
alpha = bytes - 1;
|
||||
|
||||
while (scale <= 0.5)
|
||||
{
|
||||
scale *= 2;
|
||||
level++;
|
||||
}
|
||||
|
||||
if (level > 0)
|
||||
{
|
||||
gint width = srcPR->w / 2;
|
||||
gint height = srcPR->h / 2;
|
||||
guchar *dst = g_new (guchar, width * height * bytes);
|
||||
|
||||
reduce_pixel_region (srcPR, dst, bytes);
|
||||
level--;
|
||||
|
||||
if (level > 0)
|
||||
{
|
||||
while (level)
|
||||
{
|
||||
guchar *src = dst;
|
||||
|
||||
width = width / 2;
|
||||
height = height / 2;
|
||||
|
||||
dst = g_new (guchar, width * height * bytes);
|
||||
reduce_buffer (src, dst, bytes, width * 2, height * 2, alpha);
|
||||
g_free(src);
|
||||
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
reduce_bilinear (dstPR, dst, width, height, bytes);
|
||||
g_free (dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
reduce_bilinear_pr (dstPR, srcPR);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reduce_pixel_region (PixelRegion *srcPR,
|
||||
guchar *dst,
|
||||
gint bytes)
|
||||
{
|
||||
guchar *src_buf, *row0, *row1, *row2;
|
||||
gint y;
|
||||
gint src_width = srcPR->w;
|
||||
gint dst_width = srcPR->w/2;
|
||||
guchar *dst_ptr;
|
||||
gint alpha = 0;
|
||||
|
||||
if (pixel_region_has_alpha (srcPR))
|
||||
alpha = bytes - 1;
|
||||
|
||||
src_buf = g_new (guchar, src_width * bytes * 3);
|
||||
|
||||
row0 = src_buf;
|
||||
row1 = row0 + src_width * bytes;
|
||||
row2 = row1 + src_width * bytes;
|
||||
|
||||
dst_ptr = dst;
|
||||
for (y = 0 ; y < srcPR->h ; y+=2)
|
||||
{
|
||||
pixel_region_get_row (srcPR, 0, ABS(y-1), src_width, row0, 1);
|
||||
pixel_region_get_row (srcPR, 0, y , src_width, row1, 1);
|
||||
pixel_region_get_row (srcPR, 0, y+1 , src_width, row2, 1);
|
||||
|
||||
reduce_row(src_buf, dst_ptr, src_width, bytes, alpha);
|
||||
|
||||
dst_ptr += dst_width * bytes;
|
||||
}
|
||||
|
||||
g_free (src_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
reduce_buffer (const guchar *src,
|
||||
guchar *dst,
|
||||
gint bytes,
|
||||
gint width,
|
||||
gint height,
|
||||
gint alpha)
|
||||
{
|
||||
guchar *src_buf;
|
||||
guchar *row0, *row1, *row2;
|
||||
gint y, pos;
|
||||
gint dst_width = width/2;
|
||||
guchar *dstptr;
|
||||
gint rowstride = width * bytes;
|
||||
|
||||
src_buf = g_new (guchar, rowstride * 3);
|
||||
|
||||
row0 = src_buf;
|
||||
row1 = row0 + rowstride;
|
||||
row2 = row1 + rowstride;
|
||||
|
||||
dstptr = dst;
|
||||
|
||||
for (y = 0 ; y < height ; y+=2)
|
||||
{
|
||||
pos = ABS (y-1) * rowstride;
|
||||
memcpy (row0, src+pos, rowstride);
|
||||
|
||||
pos = y * rowstride;
|
||||
memcpy (row1, src+pos, rowstride);
|
||||
|
||||
pos= (y+1) * rowstride;
|
||||
memcpy (row2, src+pos, rowstride);
|
||||
|
||||
reduce_row (src_buf, dstptr, width, bytes, alpha);
|
||||
|
||||
dstptr += dst_width * bytes;
|
||||
}
|
||||
|
||||
g_free (src_buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
reduce_row (const guchar *src,
|
||||
guchar *dst,
|
||||
gint width,
|
||||
gint bytes,
|
||||
gint alpha)
|
||||
{
|
||||
|
||||
gint x, b, start;
|
||||
gdouble alpha_sum;
|
||||
gdouble sum;
|
||||
const guchar *src0;
|
||||
const guchar *src1;
|
||||
const guchar *src2;
|
||||
guchar *dstptr;
|
||||
|
||||
/* Pre calculated gausian matrix */
|
||||
/* Standard deviation = 0.71
|
||||
|
||||
12 32 12
|
||||
32 86 32
|
||||
12 32 12
|
||||
|
||||
Matrix sum is = 262
|
||||
Normalize by dividing with 273
|
||||
|
||||
*/
|
||||
|
||||
dstptr = dst;
|
||||
|
||||
src0 = src;
|
||||
src1 = src + width * bytes;
|
||||
src2 = src1 + width * bytes;
|
||||
|
||||
start = bytes -1;
|
||||
sum = 0.0;
|
||||
alpha_sum = 0.0;
|
||||
|
||||
for (x=0; x < width ; x+=2)
|
||||
{
|
||||
for (b = start ; b >= 0 ; b--)
|
||||
{
|
||||
sum += src0[ABS(x-1) * bytes + b] * 12;
|
||||
sum += src0[ABS(x) * bytes + b] * 32;
|
||||
sum += src0[ABS(x+1) * bytes + b] * 12;
|
||||
|
||||
sum += src1[ABS(x-1) * bytes + b] * 32;
|
||||
sum += src1[ABS(x) * bytes + b] * 86;
|
||||
sum += src1[ABS(x+1) * bytes + b] * 32;
|
||||
|
||||
sum += src2[ABS(x-1) * bytes + b] * 12;
|
||||
sum += src2[ABS(x) * bytes + b] * 32;
|
||||
sum += src2[ABS(x+1) * bytes + b] * 12;
|
||||
|
||||
sum /= 273.0;
|
||||
|
||||
if ( alpha && (b == alpha))
|
||||
{
|
||||
alpha_sum = sum;
|
||||
dstptr[b] = (guchar)alpha_sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha)
|
||||
{
|
||||
if (alpha_sum != 0.0)
|
||||
sum = sum * ( 262.0 / alpha_sum );
|
||||
else
|
||||
sum = 0.0;
|
||||
}
|
||||
|
||||
dstptr[b] = (guchar) sum;
|
||||
}
|
||||
}
|
||||
|
||||
dstptr += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
reduce_bilinear (PixelRegion *dstPR,
|
||||
const guchar *src,
|
||||
gint source_w,
|
||||
gint source_h,
|
||||
gint bytes)
|
||||
{
|
||||
const gdouble scale = (gdouble) dstPR->h / (gdouble) source_h;
|
||||
|
||||
gint x, y, b;
|
||||
gint x0, x1, y0, y1;
|
||||
gdouble xfrac, yfrac;
|
||||
gdouble s00, s01, s10, s11;
|
||||
guchar value;
|
||||
guchar *dst;
|
||||
|
||||
dst = g_new (guchar, dstPR->w * dstPR->h * bytes);
|
||||
|
||||
for (y = 0; y < dstPR->h; y++)
|
||||
{
|
||||
yfrac = ( y / scale );
|
||||
y0 = (gint) floor (yfrac);
|
||||
y1 = (gint) ceil (yfrac);
|
||||
yfrac = yfrac - y0;
|
||||
|
||||
for (x = 0; x < dstPR->w; x++)
|
||||
{
|
||||
xfrac = (x / scale);
|
||||
x0 = (gint) floor (xfrac);
|
||||
x1 = (gint) ceil (xfrac);
|
||||
xfrac = xfrac - x0;
|
||||
|
||||
for (b = 0 ; b < bytes ; b++)
|
||||
{
|
||||
s00 = src[(x0 + y0 * source_w) * bytes + b];
|
||||
s10 = src[(x1 + y0 * source_w) * bytes + b];
|
||||
s01 = src[(x0 + y1 * source_w) * bytes + b];
|
||||
s11 = src[(x1 + y1 * source_w) * bytes + b];
|
||||
|
||||
value = (gint)((1 - yfrac) * ((1 - xfrac) * s00 + xfrac * s01)
|
||||
+ yfrac * ((1 - xfrac) * s10 + xfrac * s11));
|
||||
|
||||
dst[x * bytes + b] = value;
|
||||
}
|
||||
}
|
||||
|
||||
pixel_region_set_row (dstPR, 0, y, dstPR->w, dst);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reduce_bilinear_pr (PixelRegion *dstPR,
|
||||
PixelRegion *srcPR)
|
||||
{
|
||||
const gint bytes = dstPR->bytes;
|
||||
gint x, y, b;
|
||||
gint x0, x1, y0, y1;
|
||||
|
||||
gdouble scale;
|
||||
gdouble xfrac, yfrac;
|
||||
gdouble s00, s01, s10, s11;
|
||||
|
||||
guchar value;
|
||||
guchar *dst;
|
||||
guchar *src0;
|
||||
guchar *src1;
|
||||
|
||||
/* Copy and return if scale = 1.0 */
|
||||
if (srcPR->h == dstPR->h)
|
||||
{
|
||||
copy_region (srcPR, dstPR);
|
||||
return;
|
||||
}
|
||||
|
||||
scale = (gdouble) dstPR->h / (gdouble) srcPR->h;
|
||||
|
||||
/* Interpolate */
|
||||
src0 = g_new0 (guchar, srcPR->w * bytes);
|
||||
src1 = g_new0 (guchar, srcPR->w * bytes);
|
||||
dst = g_new0 (guchar, dstPR->w * bytes);
|
||||
|
||||
for (y = 0; y < dstPR->h; y++)
|
||||
{
|
||||
yfrac = y / scale;
|
||||
y0 = (gint) floor (yfrac);
|
||||
y1 = (gint) ceil (yfrac);
|
||||
yfrac = yfrac - y0;
|
||||
|
||||
pixel_region_get_row (srcPR, 0, y0, srcPR->w, src0, 1);
|
||||
pixel_region_get_row (srcPR, 0, y1, srcPR->w, src1, 1);
|
||||
|
||||
for (x = 0; x < dstPR->w; x++)
|
||||
{
|
||||
xfrac = (x / scale);
|
||||
x0 = (gint)floor(xfrac);
|
||||
x1 = (gint)ceil(xfrac);
|
||||
xfrac = xfrac - x0;
|
||||
|
||||
for (b = 0 ; b < bytes ; b++)
|
||||
{
|
||||
s00 = src0[x0 * bytes + b];
|
||||
s01 = src0[x1 * bytes + b];
|
||||
s10 = src1[x0 * bytes + b];
|
||||
s11 = src1[x1 * bytes + b];
|
||||
value = (1 - yfrac) * ( (1 - xfrac) * s00 + xfrac * s01 )
|
||||
+ yfrac * ( (1 - xfrac) * s10 + xfrac * s11 );
|
||||
|
||||
dst[x * bytes + b] = (guchar) value;
|
||||
}
|
||||
}
|
||||
|
||||
pixel_region_set_row (dstPR, 0, y, dstPR->w, dst);
|
||||
}
|
||||
|
||||
g_free(src0);
|
||||
g_free(src1);
|
||||
g_free(dst);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __REDUCE_REGION_H__
|
||||
#define __REDUCE_REGION_H__
|
||||
|
||||
|
||||
void reduce_region (PixelRegion *srcPR,
|
||||
PixelRegion *destPR,
|
||||
GimpProgressFunc progress_callback,
|
||||
gpointer progress_data);
|
||||
|
||||
|
||||
#endif /* __REDUCE_REGION_H__ */
|
Loading…
Reference in a new issue