use type introspection for vipsinterpolate too
This commit is contained in:
parent
1328958163
commit
7496082f2c
@ -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
4
TODO
@ -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 */
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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*/
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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>
|
||||
|
@ -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*/
|
||||
|
@ -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*/
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 ) );
|
||||
}
|
||||
|
@ -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 ) ) );
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user