use type introspection for vipsinterpolate too

This commit is contained in:
John Cupitt 2008-11-30 09:32:18 +00:00
parent 1328958163
commit 7496082f2c
19 changed files with 336 additions and 693 deletions

View File

@ -17,6 +17,8 @@
- moved im_format_t to VipsFormat, now sits over VipsObject
- IM_FORMAT_FLAG_PARTIAL -> VIPS_FORMAT_PARTIAL
- updated docs
- interpolators use type introspection
- added vips --list interpolators
11/9/08 started 7.16.3
- oop typo in manpage for im_project()

4
TODO
View File

@ -1,3 +1,7 @@
- nip2 Interpolate needs updating to new affinei thing
- started adding
#define IM_TYPE_GOBJECT "gobject" /* A GObject of a specified class */

View File

@ -1,7 +1,7 @@
\section{Function dispatch and plug-ins}
As image processing libraries increase in size it becomes progressively more
difficult to build applications which present the operations the libbrary
difficult to build applications which present the operations the library
offers to the user. Every time a new operation is added, every user interface
needs to be adapted --- a job which can rapidly become unmanageable.

View File

@ -3,7 +3,6 @@ pkginclude_HEADERS = \
VError.h \
VImage.h \
VMask.h \
bicubic.h \
vipscpp.h \
colour.h \
debug.h \
@ -25,8 +24,6 @@ pkginclude_HEADERS = \
meta.h \
version.h \
vips.h \
yafrsmooth.h \
yafrnohalo.h \
vips \
intl.h \
buf.h \

View File

@ -1,86 +0,0 @@
/* Bicubic (catmull-rom) interpolator.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef VIPS_BICUBIC_H
#define VIPS_BICUBIC_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#define VIPS_TYPE_INTERPOLATE_BICUBIC \
(vips_interpolate_bicubic_get_type())
#define VIPS_INTERPOLATE_BICUBIC( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubic ))
#define VIPS_INTERPOLATE_BICUBIC_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubicClass))
#define VIPS_IS_INTERPOLATE_BICUBIC( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_BICUBIC ))
#define VIPS_IS_INTERPOLATE_BICUBIC_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_BICUBIC ))
#define VIPS_INTERPOLATE_BICUBIC_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubicClass ))
typedef struct _VipsInterpolateBicubic {
VipsInterpolate parent_object;
} VipsInterpolateBicubic;
typedef struct _VipsInterpolateBicubicClass {
VipsInterpolateClass parent_class;
/* Precalculated interpolation matricies. int (used for pel sizes up
* to short), and double (for all others). We go to scale + 1, so
* we can round-to-nearest safely.
*/
/* We could keep a large set of 2d 4x4 matricies, but this actually
* works out slower, since for many resizes the thing will no longer
* fit in L1.
*/
int matrixi[VIPS_TRANSFORM_SCALE + 1][4];
double matrixf[VIPS_TRANSFORM_SCALE + 1][4];
} VipsInterpolateBicubicClass;
GType vips_interpolate_bicubic_get_type( void );
VipsInterpolate *vips_interpolate_bicubic_new( void );
/* Convenience: return a static default bicubic, so no need to free it.
*/
VipsInterpolate *vips_interpolate_bicubic_static( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*VIPS_BICUBIC_H*/

View File

@ -75,7 +75,7 @@ typedef struct _VipsInterpolateClass {
*/
int (*get_window_size)( VipsInterpolate * );
/* Or just set this if you want constant.
/* Or just set this if you want a constant.
*/
int window_size;
} VipsInterpolateClass;
@ -86,44 +86,6 @@ void vips_interpolate( VipsInterpolate *interpolate,
VipsInterpolateMethod vips_interpolate_get_method( VipsInterpolate * );
int vips_interpolate_get_window_size( VipsInterpolate *interpolate );
/* Nearest class starts.
*/
#define VIPS_TYPE_INTERPOLATE_NEAREST (vips_interpolate_nearest_get_type())
#define VIPS_INTERPOLATE_NEAREST( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_NEAREST, VipsInterpolateNearest ))
#define VIPS_INTERPOLATE_NEAREST_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_NEAREST, VipsInterpolateNearestClass))
#define VIPS_IS_INTERPOLATE_NEAREST( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_NEAREST ))
#define VIPS_IS_INTERPOLATE_NEAREST_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_NEAREST ))
#define VIPS_INTERPOLATE_NEAREST_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_NEAREST, VipsInterpolateNearestClass ))
typedef struct _VipsInterpolateNearest {
VipsInterpolate parent_object;
} VipsInterpolateNearest;
typedef struct _VipsInterpolateNearestClass {
VipsInterpolateClass parent_class;
} VipsInterpolateNearestClass;
VipsInterpolate *vips_interpolate_nearest_new( void );
GType vips_interpolate_nearest_get_type( void );
/* Convenience: return a static fast nearest, so no need to free it.
*/
VipsInterpolate *vips_interpolate_nearest_static( void );
/* Bilinear class starts.
*/
/* How many bits of precision we keep for transformations, ie. how many
* pre-computed matricies we have.
*/
@ -138,44 +100,20 @@ VipsInterpolate *vips_interpolate_nearest_static( void );
#define VIPS_INTERPOLATE_SHIFT (8)
#define VIPS_INTERPOLATE_SCALE (1 << VIPS_INTERPOLATE_SHIFT)
#define VIPS_TYPE_INTERPOLATE_BILINEAR (vips_interpolate_bilinear_get_type())
#define VIPS_INTERPOLATE_BILINEAR( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_BILINEAR, VipsInterpolateBilinear ))
#define VIPS_INTERPOLATE_BILINEAR_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_BILINEAR, VipsInterpolateBilinearClass))
#define VIPS_IS_INTERPOLATE_BILINEAR( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_BILINEAR ))
#define VIPS_IS_INTERPOLATE_BILINEAR_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_BILINEAR ))
#define VIPS_INTERPOLATE_BILINEAR_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_BILINEAR, VipsInterpolateBilinearClass ))
typedef struct _VipsInterpolateBilinear {
VipsInterpolate parent_object;
} VipsInterpolateBilinear;
typedef struct _VipsInterpolateBilinearClass {
VipsInterpolateClass parent_class;
/* Precalculated interpolation matricies. int (used for pel sizes up
* to short), and float (for all others). We go to scale + 1, so
* we can round-to-nearest safely. Don't bother with double, since
* this is an approximation anyway.
*/
int matrixi[VIPS_TRANSFORM_SCALE + 1][VIPS_TRANSFORM_SCALE + 1][4];
float matrixd[VIPS_TRANSFORM_SCALE + 1][VIPS_TRANSFORM_SCALE + 1][4];
} VipsInterpolateBilinearClass;
GType vips_interpolate_bilinear_get_type( void );
VipsInterpolate *vips_interpolate_bilinear_new( void );
/* Convenience: return a static bilinear, so no need to free it.
/* Convenience: return static interpolators, no need to unref.
*/
VipsInterpolate *vips_interpolate_nearest_static( void );
VipsInterpolate *vips_interpolate_bilinear_static( void );
VipsInterpolate *vips_interpolate_bicubic_static( void );
/* Convenience: make an interpolator from a nickname. g_object_unref() when
* you're done with it.
*/
VipsInterpolate *vips_interpolate_new( const char *nickname );
/* Register base vips types, called during startup.
*/
void vips__interpolate_init( void );
#ifdef __cplusplus
}

View File

@ -306,6 +306,7 @@ typedef void *(*VipsClassMap)( VipsObjectClass *, void * );
void *vips_type_map( GType base, VipsTypeMap2 fn, void *a, void *b );
void *vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a );
void *vips_class_map_concrete_all( GType base, VipsClassMap fn, void *a );
VipsObjectClass *vips_class_find( const char *basename, const char *nickname );
GType vips_type_find( const char *basename, const char *nickname );
char *im_strncpy( char *dest, const char *src, int n );

View File

@ -501,9 +501,6 @@ typedef struct {
#include <vips/dispatch.h>
#include <vips/region.h>
#include <vips/interpolate.h>
#include <vips/yafrsmooth.h>
#include <vips/yafrnohalo.h>
#include <vips/bicubic.h>
#include <vips/semaphore.h>
#include <vips/threadgroup.h>
#include <vips/meta.h>

View File

@ -1,100 +0,0 @@
/* YAFRNOHALO interpolator.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef VIPS_YAFRNOHALO_H
#define VIPS_YAFRNOHALO_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#define VIPS_TYPE_INTERPOLATE_YAFRNOHALO (vips_interpolate_yafrnohalo_get_type())
#define VIPS_INTERPOLATE_YAFRNOHALO( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, VipsInterpolateYafrnohalo ))
#define VIPS_INTERPOLATE_YAFRNOHALO_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, VipsInterpolateYafrnohaloClass))
#define VIPS_IS_INTERPOLATE_YAFRNOHALO( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_YAFRNOHALO ))
#define VIPS_IS_INTERPOLATE_YAFRNOHALO_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_YAFRNOHALO ))
#define VIPS_INTERPOLATE_YAFRNOHALO_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, VipsInterpolateYafrnohaloClass ))
typedef struct _VipsInterpolateYafrnohalo {
VipsInterpolate parent_object;
/* "sharpening" is a continuous method parameter which is
* proportional to the amount of "diagonal straightening" which the
* nonlinear correction part of the method may add to the underlying
* linear scheme. You may also think of it as a sharpening
* parameter: higher values correspond to more sharpening, and
* negative values lead to strange looking effects.
*
* The default value is sharpening = 4/3 when the scheme being
* "straightened" is bilinear---as is the case here. This value
* fixes key pixel values near the diagonal boundary between two
* monochrome regions (the diagonal boundary pixel values being set
* to the halfway colour).
*
* If resampling seems to add unwanted texture artifacts, push
* sharpening toward 0. It is not generally not recommended to set
* sharpening to a value larger than 2.
*
* In order to simplify interfacing with users, the parameter which
* should be set by the user is normalized so that user_sharpening =
* 1 when sharpening is equal to the recommended value. Consistently
* with the above discussion, values of user_sharpening between 0
* and about 1.5 give good results.
*/
double sharpening;
} VipsInterpolateYafrnohalo;
typedef struct _VipsInterpolateYafrnohaloClass {
VipsInterpolateClass parent_class;
} VipsInterpolateYafrnohaloClass;
GType vips_interpolate_yafrnohalo_get_type( void );
VipsInterpolate *vips_interpolate_yafrnohalo_new( void );
void vips_interpolate_yafrnohalo_set_sharpening( VipsInterpolateYafrnohalo *,
double sharpening );
/* Convenience: return a static default yafrnohalo, so no need to free it.
*/
VipsInterpolate *vips_interpolate_yafrnohalo_static( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*VIPS_YAFRNOHALO_H*/

View File

@ -1,118 +0,0 @@
/* Yafrsmooth (catmull-rom) interpolator.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef VIPS_YAFRSMOOTH_H
#define VIPS_YAFRSMOOTH_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#define VIPS_TYPE_INTERPOLATE_YAFRSMOOTH \
(vips_interpolate_yafrsmooth_get_type())
#define VIPS_INTERPOLATE_YAFRSMOOTH( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, VipsInterpolateYafrsmooth ))
#define VIPS_INTERPOLATE_YAFRSMOOTH_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, VipsInterpolateYafrsmoothClass))
#define VIPS_IS_INTERPOLATE_YAFRSMOOTH( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_YAFRSMOOTH ))
#define VIPS_IS_INTERPOLATE_YAFRSMOOTH_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_YAFRSMOOTH ))
#define VIPS_INTERPOLATE_YAFRSMOOTH_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, VipsInterpolateYafrsmoothClass ))
typedef struct _VipsInterpolateYafrsmooth {
VipsInterpolate parent_object;
/* "sharpening" is a continuous method parameter which is
* proportional to the amount of "diagonal straightening" which the
* nonlinear correction part of the method may add to the underlying
* linear scheme. You may also think of it as a sharpening
* parameter: higher values correspond to more sharpening, and
* negative values lead to strange looking effects.
*
* The default value is sharpening = 29/32 when the scheme being
* "straightened" is Catmull-Rom---as is the case here. This value
* fixes key pixel values near the diagonal boundary between two
* monochrome regions (the diagonal boundary pixel values being set
* to the halfway colour).
*
* If resampling seems to add unwanted texture artifacts, push
* sharpening toward 0. It is not generally not recommended to set
* sharpening to a value larger than 4.
*
* Sharpening is halved because the .5 which has to do with the
* relative coordinates of the evaluation points (which has to do
* with .5*rite_width etc) is folded into the constant to save
* flops. Consequently, the largest recommended value of
* sharpening_over_two is 2=4/2.
*
* In order to simplify interfacing with users, the parameter which
* should be set by the user is normalized so that user_sharpening =
* 1 when sharpening is equal to the recommended value. Consistently
* with the above discussion, values of user_sharpening between 0
* and about 3.625 give good results.
*/
double sharpening;
} VipsInterpolateYafrsmooth;
typedef struct _VipsInterpolateYafrsmoothClass {
VipsInterpolateClass parent_class;
/* Precalculated interpolation matricies. int (used for pel sizes up
* to short), and double (for all others). We go to scale + 1, so
* we can round-to-nearest safely.
*/
/* We could keep a large set of 2d 4x4 matricies, but this actually
* works out slower, since for many resizes the thing will no longer
* fit in L1.
*/
int matrixi[VIPS_TRANSFORM_SCALE + 1][4];
double matrixf[VIPS_TRANSFORM_SCALE + 1][4];
} VipsInterpolateYafrsmoothClass;
GType vips_interpolate_yafrsmooth_get_type( void );
VipsInterpolate *vips_interpolate_yafrsmooth_new( void );
void vips_interpolate_yafrsmooth_set_sharpening( VipsInterpolateYafrsmooth *,
double sharpening );
/* Convenience: return a static default yafrsmooth, so no need to free it.
*/
VipsInterpolate *vips_interpolate_yafrsmooth_static( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*VIPS_YAFRSMOOTH_H*/

View File

@ -131,13 +131,11 @@ im_init_world( const char *argv0 )
bindtextdomain( GETTEXT_PACKAGE, name );
bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
/* Start up converters for builtin types.
/* Register base vips types.
*/
im__meta_init_types();
/* Add the base format load/save operations.
*/
im__format_init();
vips__interpolate_init();
/* Load up any plugins in the vips libdir. We don't error on failure,
* it's too annoying to have VIPS refuse to start because of a broken

View File

@ -315,12 +315,12 @@ vips_class_map_concrete_all( GType type, VipsClassMap fn, void *a )
static void *
test_name( VipsObjectClass *class, const char *nickname )
{
if( strcasecmp( class->nickname, nickname ) != 0 )
if( strcasecmp( class->nickname, nickname ) == 0 )
return( class );
/* Check the class name too, why not.
*/
if( strcasecmp( G_OBJECT_CLASS_NAME( class ), nickname ) != 0 )
if( strcasecmp( G_OBJECT_CLASS_NAME( class ), nickname ) == 0 )
return( class );
return( NULL );
@ -351,6 +351,20 @@ vips_class_find( const char *basename, const char *nickname )
return( class );
}
GType
vips_type_find( const char *basename, const char *nickname )
{
VipsObjectClass *class;
if( !(class = vips_class_find( "VipsInterpolate", nickname )) )
return( 0 );
/* FIXME ... we've not supposed to use G_TYPE_FROM_CLASS(), I think.
* I'm not * sure what the alternative is.
*/
return( G_TYPE_FROM_CLASS( class ) );
}
/* Like strncpy(), but always NULL-terminate, and don't pad with NULLs.
*/
char *

View File

@ -52,7 +52,49 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
static VipsInterpolateClass *vips_interpolate_bicubic_parent_class = NULL;
#define VIPS_TYPE_INTERPOLATE_BICUBIC \
(vips_interpolate_bicubic_get_type())
#define VIPS_INTERPOLATE_BICUBIC( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubic ))
#define VIPS_INTERPOLATE_BICUBIC_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubicClass))
#define VIPS_IS_INTERPOLATE_BICUBIC( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_BICUBIC ))
#define VIPS_IS_INTERPOLATE_BICUBIC_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_BICUBIC ))
#define VIPS_INTERPOLATE_BICUBIC_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_BICUBIC, VipsInterpolateBicubicClass ))
typedef struct _VipsInterpolateBicubic {
VipsInterpolate parent_object;
} VipsInterpolateBicubic;
typedef struct _VipsInterpolateBicubicClass {
VipsInterpolateClass parent_class;
/* Precalculated interpolation matricies. int (used for pel sizes up
* to short), and double (for all others). We go to scale + 1, so
* we can round-to-nearest safely.
*/
/* We could keep a large set of 2d 4x4 matricies, but this actually
* works out slower, since for many resizes the thing will no longer
* fit in L1.
*/
int matrixi[VIPS_TRANSFORM_SCALE + 1][4];
double matrixf[VIPS_TRANSFORM_SCALE + 1][4];
} VipsInterpolateBicubicClass;
/* We need C linkage for this.
*/
extern "C" {
G_DEFINE_TYPE( VipsInterpolateBicubic, vips_interpolate_bicubic,
VIPS_TYPE_INTERPOLATE );
}
/* Pointers to write to / read from, number of bands,
* how many bytes to add to move down a line.
@ -384,9 +426,6 @@ vips_interpolate_bicubic_class_init( VipsInterpolateBicubicClass *iclass )
VipsInterpolateClass *interpolate_class =
VIPS_INTERPOLATE_CLASS( iclass );
vips_interpolate_bicubic_parent_class =
VIPS_INTERPOLATE_CLASS( g_type_class_peek_parent( iclass ) );
object_class->nickname = "bicubic";
object_class->description = _( "Bicubic interpolation (Catmull-Rom)" );
@ -416,48 +455,3 @@ vips_interpolate_bicubic_init( VipsInterpolateBicubic *bicubic )
}
GType
vips_interpolate_bicubic_get_type()
{
static GType type = 0;
if( !type ) {
static const GTypeInfo info = {
sizeof( VipsInterpolateBicubicClass ),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) vips_interpolate_bicubic_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof( VipsInterpolateBicubic ),
32, /* n_preallocs */
(GInstanceInitFunc) vips_interpolate_bicubic_init,
};
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
"VipsInterpolateBicubic", &info,
(GTypeFlags) 0 );
}
return( type );
}
VipsInterpolate *
vips_interpolate_bicubic_new( void )
{
return( VIPS_INTERPOLATE( g_object_new(
VIPS_TYPE_INTERPOLATE_BICUBIC, NULL ) ) );
}
/* Convenience: return a static bicubic you don't need to free.
*/
VipsInterpolate *
vips_interpolate_bicubic_static( void )
{
static VipsInterpolate *interpolate = NULL;
if( !interpolate )
interpolate = vips_interpolate_bicubic_new();
return( interpolate );
}

View File

@ -516,7 +516,7 @@ im_affine( IMAGE *in, IMAGE *out,
int ox, int oy, int ow, int oh )
{
return( im_affinei( in, out,
vips_interpolate_bicubic_static(),
vips_interpolate_bilinear_static(),
a, b, c, d, dx, dy,
ox, oy, ow, oh ) );
}

View File

@ -52,9 +52,7 @@
*/
#define FLOOR( V ) ((V) >= 0 ? (int)(V) : (int)((V) - 1))
static VipsInterpolateClass *vips_interpolate_parent_class = NULL;
static VipsInterpolateClass *vips_interpolate_nearest_parent_class = NULL;
static VipsInterpolateClass *vips_interpolate_bilinear_parent_class = NULL;
G_DEFINE_ABSTRACT_TYPE( VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT );
#ifdef DEBUG
static void
@ -84,8 +82,6 @@ vips_interpolate_class_init( VipsInterpolateClass *class )
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
#endif /*DEBUG*/
vips_interpolate_parent_class = g_type_class_peek_parent( class );
#ifdef DEBUG
gobject_class->finalize = vips_interpolate_finalize;
#endif /*DEBUG*/
@ -103,31 +99,6 @@ vips_interpolate_init( VipsInterpolate *interpolate )
#endif /*DEBUG*/
}
GType
vips_interpolate_get_type( void )
{
static GType type = 0;
if( !type ) {
static const GTypeInfo info = {
sizeof( VipsInterpolateClass ),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) vips_interpolate_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof( VipsInterpolate ),
32, /* n_preallocs */
(GInstanceInitFunc) vips_interpolate_init,
};
type = g_type_register_static( VIPS_TYPE_OBJECT,
"VipsInterpolate", &info, 0 );
}
return( type );
}
/* Set the point out_x, out_y in REGION out to be the point interpolated at
* in_x, in_y in REGION in. Don't do this as a signal ffor speed.
*/
@ -168,6 +139,29 @@ vips_interpolate_get_window_size( VipsInterpolate *interpolate )
/* VipsInterpolateNearest class
*/
#define VIPS_TYPE_INTERPOLATE_NEAREST (vips_interpolate_nearest_get_type())
#define VIPS_INTERPOLATE_NEAREST( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_NEAREST, VipsInterpolateNearest ))
#define VIPS_INTERPOLATE_NEAREST_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_NEAREST, VipsInterpolateNearestClass))
#define VIPS_IS_INTERPOLATE_NEAREST( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_NEAREST ))
#define VIPS_IS_INTERPOLATE_NEAREST_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_NEAREST ))
#define VIPS_INTERPOLATE_NEAREST_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_NEAREST, VipsInterpolateNearestClass ))
/* No new members.
*/
typedef VipsInterpolate VipsInterpolateNearest;
typedef VipsInterpolateClass VipsInterpolateNearestClass;
G_DEFINE_TYPE( VipsInterpolateNearest, vips_interpolate_nearest,
VIPS_TYPE_INTERPOLATE );
static void
vips_interpolate_nearest_interpolate( VipsInterpolate *interpolate,
PEL *out, REGION *in, double x, double y )
@ -191,11 +185,12 @@ vips_interpolate_nearest_interpolate( VipsInterpolate *interpolate,
static void
vips_interpolate_nearest_class_init( VipsInterpolateNearestClass *class )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
VipsInterpolateClass *interpolate_class =
VIPS_INTERPOLATE_CLASS( class );
vips_interpolate_nearest_parent_class =
g_type_class_peek_parent( class );
object_class->nickname = "nearest";
object_class->description = _( "Nearest-neighbour interpolation" );
interpolate_class->interpolate = vips_interpolate_nearest_interpolate;
interpolate_class->window_size = 1;
@ -208,32 +203,6 @@ vips_interpolate_nearest_init( VipsInterpolateNearest *nearest )
printf( "vips_interpolate_nearest_init: " );
vips_object_print( VIPS_OBJECT( nearest ) );
#endif /*DEBUG*/
}
GType
vips_interpolate_nearest_get_type( void )
{
static GType type = 0;
if( !type ) {
static const GTypeInfo info = {
sizeof( VipsInterpolateNearestClass ),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) vips_interpolate_nearest_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof( VipsInterpolateNearest ),
32, /* n_preallocs */
(GInstanceInitFunc) vips_interpolate_nearest_init,
};
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
"VipsInterpolateNearest", &info, 0 );
}
return( type );
}
VipsInterpolate *
@ -259,6 +228,38 @@ vips_interpolate_nearest_static( void )
/* VipsInterpolateBilinear class
*/
#define VIPS_TYPE_INTERPOLATE_BILINEAR (vips_interpolate_bilinear_get_type())
#define VIPS_INTERPOLATE_BILINEAR( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_BILINEAR, VipsInterpolateBilinear ))
#define VIPS_INTERPOLATE_BILINEAR_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_BILINEAR, VipsInterpolateBilinearClass))
#define VIPS_IS_INTERPOLATE_BILINEAR( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_BILINEAR ))
#define VIPS_IS_INTERPOLATE_BILINEAR_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_BILINEAR ))
#define VIPS_INTERPOLATE_BILINEAR_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_BILINEAR, VipsInterpolateBilinearClass ))
typedef VipsInterpolate VipsInterpolateBilinear;
typedef struct _VipsInterpolateBilinearClass {
VipsInterpolateClass parent_class;
/* Precalculated interpolation matricies. int (used for pel sizes up
* to short), and float (for all others). We go to scale + 1, so
* we can round-to-nearest safely. Don't bother with double, since
* this is an approximation anyway.
*/
int matrixi[VIPS_TRANSFORM_SCALE + 1][VIPS_TRANSFORM_SCALE + 1][4];
float matrixd[VIPS_TRANSFORM_SCALE + 1][VIPS_TRANSFORM_SCALE + 1][4];
} VipsInterpolateBilinearClass;
G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
VIPS_TYPE_INTERPOLATE );
/* in this class, name vars in the 2x2 grid as eg.
* p1 p2
* p3 p4
@ -364,12 +365,13 @@ vips_interpolate_bilinear_interpolate( VipsInterpolate *interpolate,
static void
vips_interpolate_bilinear_class_init( VipsInterpolateBilinearClass *class )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
VipsInterpolateClass *interpolate_class =
(VipsInterpolateClass *) class;
int x, y;
vips_interpolate_bilinear_parent_class =
g_type_class_peek_parent( class );
object_class->nickname = "bilinear";
object_class->description = _( "Bilinear interpolation" );
interpolate_class->interpolate = vips_interpolate_bilinear_interpolate;
interpolate_class->window_size = 2;
@ -417,31 +419,6 @@ vips_interpolate_bilinear_init( VipsInterpolateBilinear *bilinear )
}
GType
vips_interpolate_bilinear_get_type( void )
{
static GType type = 0;
if( !type ) {
static const GTypeInfo info = {
sizeof( VipsInterpolateBilinearClass ),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) vips_interpolate_bilinear_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof( VipsInterpolateBilinear ),
32, /* n_preallocs */
(GInstanceInitFunc) vips_interpolate_bilinear_init,
};
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
"VipsInterpolateBilinear", &info, 0 );
}
return( type );
}
VipsInterpolate *
vips_interpolate_bilinear_new( void )
{
@ -462,3 +439,31 @@ vips_interpolate_bilinear_static( void )
return( interpolate );
}
/* Called on startup: register the base vips interpolators.
*/
void
vips__interpolate_init( void )
{
extern GType vips_interpolate_bicubic_get_type( void );
extern GType vips_interpolate_yafrsmooth_get_type( void );
extern GType vips_interpolate_yafrnohalo_get_type( void );
vips_interpolate_nearest_get_type();
vips_interpolate_bilinear_get_type();
vips_interpolate_bicubic_get_type();
vips_interpolate_yafrsmooth_get_type();
vips_interpolate_yafrnohalo_get_type();
}
/* Make an interpolator from a nickname.
*/
VipsInterpolate *
vips_interpolate_new( const char *nickname )
{
GType type;
if( !(type = vips_type_find( "VipsInterpolate", nickname )) )
return( NULL );
return( VIPS_INTERPOLATE( g_object_new( type, NULL ) ) );
}

View File

@ -522,7 +522,7 @@ static im_function affine_desc = {
static im_arg_desc affinei_args[] = {
IM_INPUT_IMAGE( "in" ),
IM_OUTPUT_IMAGE( "out" ),
IM_INPUT_INT( "interpolate" ),
IM_INPUT_STRING( "interpolate" ),
IM_INPUT_DOUBLE( "a" ),
IM_INPUT_DOUBLE( "b" ),
IM_INPUT_DOUBLE( "c" ),
@ -535,46 +535,12 @@ static im_arg_desc affinei_args[] = {
IM_INPUT_INT( "h" )
};
static VipsInterpolate *
get_interpolate( int interpol )
{
VipsInterpolate *interpolate;
switch( interpol ) {
case 1:
interpolate = vips_interpolate_nearest_new();
break;
case 2:
interpolate = vips_interpolate_bilinear_new();
break;
case 3:
interpolate = vips_interpolate_bicubic_new();
break;
case 4:
interpolate = vips_interpolate_yafrsmooth_new();
break;
case 5:
interpolate = vips_interpolate_yafrnohalo_new();
break;
default:
im_error( "affinei_vec", "%s", _( "bad interpolation" ) );
interpolate = NULL;
}
return( interpolate );
}
/* Call im_affinei via arg vector.
*/
static int
affinei_vec( im_object *argv )
{
int interpol = *((int *) argv[2]);
const char *interpol = argv[2];
double a = *((double *) argv[3]);
double b = *((double *) argv[4]);
double c = *((double *) argv[5]);
@ -588,7 +554,7 @@ affinei_vec( im_object *argv )
VipsInterpolate *interpolate;
int result;
if( !(interpolate = get_interpolate( interpol )) )
if( !(interpolate = vips_interpolate_new( interpol )) )
return( -1 );
result = im_affinei( argv[0], argv[1], interpolate,
a, b, c, d, dx, dy, x, y, w, h );
@ -613,7 +579,7 @@ static im_function affinei_desc = {
static im_arg_desc affinei_all_args[] = {
IM_INPUT_IMAGE( "in" ),
IM_OUTPUT_IMAGE( "out" ),
IM_INPUT_INT( "interpolate" ),
IM_INPUT_STRING( "interpolate" ),
IM_INPUT_DOUBLE( "a" ),
IM_INPUT_DOUBLE( "b" ),
IM_INPUT_DOUBLE( "c" ),
@ -627,7 +593,7 @@ static im_arg_desc affinei_all_args[] = {
static int
affinei_all_vec( im_object *argv )
{
int interpol = *((int *) argv[2]);
const char *interpol = argv[2];
double a = *((double *) argv[3]);
double b = *((double *) argv[4]);
double c = *((double *) argv[5]);
@ -637,7 +603,7 @@ affinei_all_vec( im_object *argv )
VipsInterpolate *interpolate;
int result;
if( !(interpolate = get_interpolate( interpol )) )
if( !(interpolate = vips_interpolate_new( interpol )) )
return( -1 );
result = im_affinei_all( argv[0], argv[1], interpolate,
a, b, c, d, dx, dy );

View File

@ -50,7 +50,58 @@
*/
#define FLOOR( V ) ((V) >= 0 ? (int)(V) : (int)((V) - 1))
static VipsInterpolateClass *vips_interpolate_yafrnohalo_parent_class = NULL;
#define VIPS_TYPE_INTERPOLATE_YAFRNOHALO \
(vips_interpolate_yafrnohalo_get_type())
#define VIPS_INTERPOLATE_YAFRNOHALO( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, VipsInterpolateYafrnohalo ))
#define VIPS_INTERPOLATE_YAFRNOHALO_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, VipsInterpolateYafrnohaloClass))
#define VIPS_IS_INTERPOLATE_YAFRNOHALO( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_YAFRNOHALO ))
#define VIPS_IS_INTERPOLATE_YAFRNOHALO_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_YAFRNOHALO ))
#define VIPS_INTERPOLATE_YAFRNOHALO_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, VipsInterpolateYafrnohaloClass ))
typedef struct _VipsInterpolateYafrnohalo {
VipsInterpolate parent_object;
/* "sharpening" is a continuous method parameter which is
* proportional to the amount of "diagonal straightening" which the
* nonlinear correction part of the method may add to the underlying
* linear scheme. You may also think of it as a sharpening
* parameter: higher values correspond to more sharpening, and
* negative values lead to strange looking effects.
*
* The default value is sharpening = 4/3 when the scheme being
* "straightened" is bilinear---as is the case here. This value
* fixes key pixel values near the diagonal boundary between two
* monochrome regions (the diagonal boundary pixel values being set
* to the halfway colour).
*
* If resampling seems to add unwanted texture artifacts, push
* sharpening toward 0. It is not generally not recommended to set
* sharpening to a value larger than 2.
*
* In order to simplify interfacing with users, the parameter which
* should be set by the user is normalized so that user_sharpening =
* 1 when sharpening is equal to the recommended value. Consistently
* with the above discussion, values of user_sharpening between 0
* and about 1.5 give good results.
*/
double sharpening;
} VipsInterpolateYafrnohalo;
typedef struct _VipsInterpolateYafrnohaloClass {
VipsInterpolateClass parent_class;
} VipsInterpolateYafrnohaloClass;
G_DEFINE_TYPE( VipsInterpolateYafrnohalo, vips_interpolate_yafrnohalo,
VIPS_TYPE_INTERPOLATE );
/* Copy-paste of gegl-sampler-yafr-nohalo.c starts
*/
@ -1007,11 +1058,12 @@ vips_interpolate_yafrnohalo_interpolate( VipsInterpolate *interpolate,
static void
vips_interpolate_yafrnohalo_class_init( VipsInterpolateYafrnohaloClass *class )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
VipsInterpolateClass *interpolate_class =
VIPS_INTERPOLATE_CLASS( class );
vips_interpolate_yafrnohalo_parent_class =
g_type_class_peek_parent( class );
object_class->nickname = "yafrnohalo";
object_class->description = _( "YAFR nohalo interpolation" );
interpolate_class->interpolate =
vips_interpolate_yafrnohalo_interpolate;
@ -1028,58 +1080,3 @@ vips_interpolate_yafrnohalo_init( VipsInterpolateYafrnohalo *yafrnohalo )
yafrnohalo->sharpening = 1.0;
}
GType
vips_interpolate_yafrnohalo_get_type( void )
{
static GType type = 0;
if( !type ) {
static const GTypeInfo info = {
sizeof( VipsInterpolateYafrnohaloClass ),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) vips_interpolate_yafrnohalo_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof( VipsInterpolateYafrnohalo ),
32, /* n_preallocs */
(GInstanceInitFunc) vips_interpolate_yafrnohalo_init,
};
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
"VipsInterpolateYafrnohalo", &info, 0 );
}
return( type );
}
VipsInterpolate *
vips_interpolate_yafrnohalo_new( void )
{
return( VIPS_INTERPOLATE( g_object_new(
VIPS_TYPE_INTERPOLATE_YAFRNOHALO, NULL ) ) );
}
void
vips_interpolate_yafrnohalo_set_sharpening(
VipsInterpolateYafrnohalo *yafrnohalo,
double sharpening )
{
yafrnohalo->sharpening = sharpening;
}
/* Convenience: return a static yafrnohalo you don't need to free.
*/
VipsInterpolate *
vips_interpolate_yafrnohalo_static( void )
{
static VipsInterpolate *interpolate = NULL;
if( !interpolate )
interpolate = vips_interpolate_yafrnohalo_new();
return( interpolate );
}

View File

@ -128,7 +128,79 @@
*/
#define SMOOTH_SHARPENING_SCALE (0.453125f)
static VipsInterpolateClass *vips_interpolate_yafrsmooth_parent_class = NULL;
#define VIPS_TYPE_INTERPOLATE_YAFRSMOOTH \
(vips_interpolate_yafrsmooth_get_type())
#define VIPS_INTERPOLATE_YAFRSMOOTH( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, VipsInterpolateYafrsmooth ))
#define VIPS_INTERPOLATE_YAFRSMOOTH_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, VipsInterpolateYafrsmoothClass))
#define VIPS_IS_INTERPOLATE_YAFRSMOOTH( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_INTERPOLATE_YAFRSMOOTH ))
#define VIPS_IS_INTERPOLATE_YAFRSMOOTH_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_INTERPOLATE_YAFRSMOOTH ))
#define VIPS_INTERPOLATE_YAFRSMOOTH_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, VipsInterpolateYafrsmoothClass ))
typedef struct _VipsInterpolateYafrsmooth {
VipsInterpolate parent_object;
/* "sharpening" is a continuous method parameter which is
* proportional to the amount of "diagonal straightening" which the
* nonlinear correction part of the method may add to the underlying
* linear scheme. You may also think of it as a sharpening
* parameter: higher values correspond to more sharpening, and
* negative values lead to strange looking effects.
*
* The default value is sharpening = 29/32 when the scheme being
* "straightened" is Catmull-Rom---as is the case here. This value
* fixes key pixel values near the diagonal boundary between two
* monochrome regions (the diagonal boundary pixel values being set
* to the halfway colour).
*
* If resampling seems to add unwanted texture artifacts, push
* sharpening toward 0. It is not generally not recommended to set
* sharpening to a value larger than 4.
*
* Sharpening is halved because the .5 which has to do with the
* relative coordinates of the evaluation points (which has to do
* with .5*rite_width etc) is folded into the constant to save
* flops. Consequently, the largest recommended value of
* sharpening_over_two is 2=4/2.
*
* In order to simplify interfacing with users, the parameter which
* should be set by the user is normalized so that user_sharpening =
* 1 when sharpening is equal to the recommended value. Consistently
* with the above discussion, values of user_sharpening between 0
* and about 3.625 give good results.
*/
double sharpening;
} VipsInterpolateYafrsmooth;
typedef struct _VipsInterpolateYafrsmoothClass {
VipsInterpolateClass parent_class;
/* Precalculated interpolation matricies. int (used for pel sizes up
* to short), and double (for all others). We go to scale + 1, so
* we can round-to-nearest safely.
*/
/* We could keep a large set of 2d 4x4 matricies, but this actually
* works out slower, since for many resizes the thing will no longer
* fit in L1.
*/
int matrixi[VIPS_TRANSFORM_SCALE + 1][4];
double matrixf[VIPS_TRANSFORM_SCALE + 1][4];
} VipsInterpolateYafrsmoothClass;
/* We need C linkage for this.
*/
extern "C" {
G_DEFINE_TYPE( VipsInterpolateYafrsmooth, vips_interpolate_yafrsmooth,
VIPS_TYPE_INTERPOLATE );
}
/* T is the type of pixels we are computing, D is a type large enough to hold
* (Ta - Tb) ** 2.
@ -668,11 +740,12 @@ vips_interpolate_yafrsmooth_interpolate( VipsInterpolate *interpolate,
static void
vips_interpolate_yafrsmooth_class_init( VipsInterpolateYafrsmoothClass *iclass )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( iclass );
VipsInterpolateClass *interpolate_class =
VIPS_INTERPOLATE_CLASS( iclass );
vips_interpolate_yafrsmooth_parent_class =
VIPS_INTERPOLATE_CLASS( g_type_class_peek_parent( iclass ) );
object_class->nickname = "yafrsmooth";
object_class->description = _( "YAFR smooth interpolation" );
interpolate_class->interpolate =
vips_interpolate_yafrsmooth_interpolate;
@ -701,59 +774,3 @@ vips_interpolate_yafrsmooth_init( VipsInterpolateYafrsmooth *yafrsmooth )
yafrsmooth->sharpening = 1.0;
}
GType
vips_interpolate_yafrsmooth_get_type()
{
static GType type = 0;
if( !type ) {
static const GTypeInfo info = {
sizeof( VipsInterpolateYafrsmoothClass ),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) vips_interpolate_yafrsmooth_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof( VipsInterpolateYafrsmooth ),
32, /* n_preallocs */
(GInstanceInitFunc) vips_interpolate_yafrsmooth_init,
};
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
"VipsInterpolateYafrsmooth", &info,
(GTypeFlags) 0 );
}
return( type );
}
VipsInterpolate *
vips_interpolate_yafrsmooth_new( void )
{
return( VIPS_INTERPOLATE( g_object_new(
VIPS_TYPE_INTERPOLATE_YAFRSMOOTH, NULL ) ) );
}
void
vips_interpolate_yafrsmooth_set_sharpening(
VipsInterpolateYafrsmooth *yafrsmooth,
double sharpening )
{
yafrsmooth->sharpening = sharpening;
}
/* Convenience: return a static yafrsmooth you don't need to free.
*/
VipsInterpolate *
vips_interpolate_yafrsmooth_static( void )
{
static VipsInterpolate *interpolate = NULL;
if( !interpolate )
interpolate = vips_interpolate_yafrsmooth_new();
return( interpolate );
}

View File

@ -26,6 +26,8 @@
* - add input *VEC arg types to C++ binding
* 17/8/08
* - add --list formats
* 29/11/08
* - add --list interpolators
*/
/*
@ -164,33 +166,43 @@ list_function( im_function *func )
}
static void *
list_format( VipsFormatClass *format )
list_format( VipsFormatClass *class )
{
const char **p;
printf( "%-20s - ",
VIPS_OBJECT_CLASS( format )->description );
VIPS_OBJECT_CLASS( class )->description );
printf( "(" );
for( p = format->suffs; *p; p++ ) {
for( p = class->suffs; *p; p++ ) {
printf( "%s", *p );
if( p[1] )
printf( ", " );
}
printf( ") " );
if( format->is_a )
if( class->is_a )
printf( "is_a " );
if( format->header )
if( class->header )
printf( "header " );
if( format->load )
if( class->load )
printf( "load " );
if( format->save )
if( class->save )
printf( "save " );
if( format->get_flags )
if( class->get_flags )
printf( "get_flags " );
printf( "\n" );
return( NULL );
}
static void *
list_interpolate( VipsInterpolateClass *class )
{
printf( "%-20s - %s\n",
VIPS_OBJECT_CLASS( class )->nickname,
VIPS_OBJECT_CLASS( class )->description );
return( NULL );
}
@ -201,6 +213,11 @@ print_list( const char *name )
im_map_packages( (VSListMap2Fn) list_package, NULL );
else if( strcmp( name, "formats" ) == 0 )
vips_format_map( (VSListMap2Fn) list_format, NULL, NULL );
else if( strcmp( name, "interpolators" ) == 0 ) {
vips_class_map_concrete_all(
g_type_from_name( "VipsInterpolate" ),
(VipsClassMap) list_interpolate, NULL );
}
else {
if( map_name( name, list_function ) )
error_exit( "unknown package \"%s\"", name );