add Mitchell kernel

see https://github.com/jcupitt/libvips/issues/966
This commit is contained in:
John Cupitt 2018-06-12 12:55:10 +01:00
parent cc29a13cc7
commit 3b1e3e1841
7 changed files with 39 additions and 18 deletions

View File

@ -28,6 +28,7 @@
- vips7 C++ interface defaults off
- make members, getters and operators "const" in cpp API
- composite has params for x/y position of sub-images [medakk]
- add Mitchell kernel
12/3/18 started 8.6.4
- better fitting of fonts with overhanging edges [Adrià]

View File

@ -98,6 +98,13 @@ typedef struct _VipsCompositeBase {
*/
gboolean premultiplied;
/* The x and y positions for each image in the stack. There are n - 1
* of these, since image 0 is always positioned at (0, 0). Set by
* subclasses. Can be NULL.
*/
int *x_offset;
int *y_offset;
/* The number of inputs. This can be less than the number of images in
* @in.
*/
@ -112,12 +119,6 @@ typedef struct _VipsCompositeBase {
*/
double max_band[MAX_BANDS + 1];
/* The x and y positions for each image in the stack. There are n - 1
* of these, since image 0 is always positioned at (0, 0).
*/
int *x_offset;
int *y_offset;
#ifdef HAVE_VECTOR_ARITH
/* max_band as a vector, for the RGBA case.
*/

View File

@ -42,6 +42,7 @@ typedef enum {
VIPS_KERNEL_NEAREST,
VIPS_KERNEL_LINEAR,
VIPS_KERNEL_CUBIC,
VIPS_KERNEL_MITCHELL,
VIPS_KERNEL_LANCZOS2,
VIPS_KERNEL_LANCZOS3,
VIPS_KERNEL_LAST

View File

@ -877,6 +877,7 @@ vips_kernel_get_type( void )
{VIPS_KERNEL_NEAREST, "VIPS_KERNEL_NEAREST", "nearest"},
{VIPS_KERNEL_LINEAR, "VIPS_KERNEL_LINEAR", "linear"},
{VIPS_KERNEL_CUBIC, "VIPS_KERNEL_CUBIC", "cubic"},
{VIPS_KERNEL_MITCHELL, "VIPS_KERNEL_MITCHELL", "mitchell"},
{VIPS_KERNEL_LANCZOS2, "VIPS_KERNEL_LANCZOS2", "lanczos2"},
{VIPS_KERNEL_LANCZOS3, "VIPS_KERNEL_LANCZOS3", "lanczos3"},
{VIPS_KERNEL_LAST, "VIPS_KERNEL_LAST", "last"},

View File

@ -104,6 +104,7 @@ vips_reduce_get_points( VipsKernel kernel, double shrink )
return( rint( 2 * shrink ) + 1 );
case VIPS_KERNEL_CUBIC:
case VIPS_KERNEL_MITCHELL:
return( rint( 4 * shrink ) + 1 );
case VIPS_KERNEL_LANCZOS2:
@ -135,7 +136,14 @@ vips_reduce_make_mask( double *c, VipsKernel kernel, double shrink, double x )
break;
case VIPS_KERNEL_CUBIC:
calculate_coefficients_adaptive_catmull( c, shrink, x );
/* Catmull-Rom.
*/
calculate_coefficients_cubic( c, shrink, x, 0.0, 0.5 );
break;
case VIPS_KERNEL_MITCHELL:
calculate_coefficients_cubic( c, shrink, x,
1.0 / 3.0, 1.0 / 3.0 );
break;
case VIPS_KERNEL_LANCZOS2:

View File

@ -128,6 +128,7 @@ vips_resize_int_shrink( VipsResize *resize, double scale )
case VIPS_KERNEL_LINEAR:
case VIPS_KERNEL_CUBIC:
case VIPS_KERNEL_MITCHELL:
case VIPS_KERNEL_LANCZOS2:
case VIPS_KERNEL_LANCZOS3:
default:

View File

@ -316,7 +316,8 @@ calculate_coefficients_catmull( double c[4], const double x )
* from the interpolator as well as from the table builder.
*/
static void inline
calculate_coefficients_triangle( double *c, const double shrink, const double x )
calculate_coefficients_triangle( double *c,
const double shrink, const double x )
{
/* Needs to be in sync with vips_reduce_get_points().
*/
@ -342,11 +343,18 @@ calculate_coefficients_triangle( double *c, const double shrink, const double x
c[i] /= sum;
}
/* Calculate a catmull kernel for shrinking.
/* Generate a cubic filter. See:
*
* Mitchell and Netravali, Reconstruction Filters in Computer Graphics
* Computer Graphics, Volume 22, Number 4, August 1988.
*
* B = 1, C = 0 - cubic B-spline
* B = 1/3, C = 1/3 - Mitchell
* B = 0, C = 1/2 - Catmull-Rom spline
*/
static void inline
calculate_coefficients_adaptive_catmull( double *c,
const double shrink, const double x )
calculate_coefficients_cubic( double *c,
const double shrink, const double x, double B, double C )
{
/* Needs to be in sync with vips_reduce_get_points().
*/
@ -361,18 +369,18 @@ calculate_coefficients_adaptive_catmull( double *c,
const double axp = VIPS_FABS( xp );
const double axp2 = axp * axp;
const double axp3 = axp2 * axp;
const double a = -0.5;
double l;
if( axp <= 1 )
l = (a + 2) * axp3 -
(a + 3) * axp2 + 1;
l = ((12 - 9 * B - 6 * C) * axp3 +
(-18 + 12 * B + 6 * C) * axp2 +
(6 - 2 * B)) / 6;
else if( axp <= 2 )
l = a * axp3 -
5 * a * axp2 +
8 * a * axp -
4 * a;
l = ((-B - 6 * C) * axp3 +
(6 * B + 30 * C) * axp2 +
(-12 * B - 48 * C) * axp +
(8 * B + 24 * C)) / 6;
else
l = 0.0;