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
|
- moved im_format_t to VipsFormat, now sits over VipsObject
|
||||||
- IM_FORMAT_FLAG_PARTIAL -> VIPS_FORMAT_PARTIAL
|
- IM_FORMAT_FLAG_PARTIAL -> VIPS_FORMAT_PARTIAL
|
||||||
- updated docs
|
- updated docs
|
||||||
|
- interpolators use type introspection
|
||||||
|
- added vips --list interpolators
|
||||||
|
|
||||||
11/9/08 started 7.16.3
|
11/9/08 started 7.16.3
|
||||||
- oop typo in manpage for im_project()
|
- 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
|
- started adding
|
||||||
|
|
||||||
#define IM_TYPE_GOBJECT "gobject" /* A GObject of a specified class */
|
#define IM_TYPE_GOBJECT "gobject" /* A GObject of a specified class */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
\section{Function dispatch and plug-ins}
|
\section{Function dispatch and plug-ins}
|
||||||
|
|
||||||
As image processing libraries increase in size it becomes progressively more
|
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
|
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.
|
needs to be adapted --- a job which can rapidly become unmanageable.
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ pkginclude_HEADERS = \
|
|||||||
VError.h \
|
VError.h \
|
||||||
VImage.h \
|
VImage.h \
|
||||||
VMask.h \
|
VMask.h \
|
||||||
bicubic.h \
|
|
||||||
vipscpp.h \
|
vipscpp.h \
|
||||||
colour.h \
|
colour.h \
|
||||||
debug.h \
|
debug.h \
|
||||||
@ -25,8 +24,6 @@ pkginclude_HEADERS = \
|
|||||||
meta.h \
|
meta.h \
|
||||||
version.h \
|
version.h \
|
||||||
vips.h \
|
vips.h \
|
||||||
yafrsmooth.h \
|
|
||||||
yafrnohalo.h \
|
|
||||||
vips \
|
vips \
|
||||||
intl.h \
|
intl.h \
|
||||||
buf.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 * );
|
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;
|
int window_size;
|
||||||
} VipsInterpolateClass;
|
} VipsInterpolateClass;
|
||||||
@ -86,44 +86,6 @@ void vips_interpolate( VipsInterpolate *interpolate,
|
|||||||
VipsInterpolateMethod vips_interpolate_get_method( VipsInterpolate * );
|
VipsInterpolateMethod vips_interpolate_get_method( VipsInterpolate * );
|
||||||
int vips_interpolate_get_window_size( VipsInterpolate *interpolate );
|
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
|
/* How many bits of precision we keep for transformations, ie. how many
|
||||||
* pre-computed matricies we have.
|
* pre-computed matricies we have.
|
||||||
*/
|
*/
|
||||||
@ -138,44 +100,20 @@ VipsInterpolate *vips_interpolate_nearest_static( void );
|
|||||||
#define VIPS_INTERPOLATE_SHIFT (8)
|
#define VIPS_INTERPOLATE_SHIFT (8)
|
||||||
#define VIPS_INTERPOLATE_SCALE (1 << VIPS_INTERPOLATE_SHIFT)
|
#define VIPS_INTERPOLATE_SCALE (1 << VIPS_INTERPOLATE_SHIFT)
|
||||||
|
|
||||||
#define VIPS_TYPE_INTERPOLATE_BILINEAR (vips_interpolate_bilinear_get_type())
|
/* Convenience: return static interpolators, no need to unref.
|
||||||
#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.
|
|
||||||
*/
|
*/
|
||||||
|
VipsInterpolate *vips_interpolate_nearest_static( void );
|
||||||
VipsInterpolate *vips_interpolate_bilinear_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
|
#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( GType base, VipsTypeMap2 fn, void *a, void *b );
|
||||||
void *vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a );
|
void *vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a );
|
||||||
void *vips_class_map_concrete_all( GType base, VipsClassMap 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 );
|
GType vips_type_find( const char *basename, const char *nickname );
|
||||||
|
|
||||||
char *im_strncpy( char *dest, const char *src, int n );
|
char *im_strncpy( char *dest, const char *src, int n );
|
||||||
|
@ -501,9 +501,6 @@ typedef struct {
|
|||||||
#include <vips/dispatch.h>
|
#include <vips/dispatch.h>
|
||||||
#include <vips/region.h>
|
#include <vips/region.h>
|
||||||
#include <vips/interpolate.h>
|
#include <vips/interpolate.h>
|
||||||
#include <vips/yafrsmooth.h>
|
|
||||||
#include <vips/yafrnohalo.h>
|
|
||||||
#include <vips/bicubic.h>
|
|
||||||
#include <vips/semaphore.h>
|
#include <vips/semaphore.h>
|
||||||
#include <vips/threadgroup.h>
|
#include <vips/threadgroup.h>
|
||||||
#include <vips/meta.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 );
|
bindtextdomain( GETTEXT_PACKAGE, name );
|
||||||
bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
|
bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
|
||||||
|
|
||||||
/* Start up converters for builtin types.
|
/* Register base vips types.
|
||||||
*/
|
*/
|
||||||
im__meta_init_types();
|
im__meta_init_types();
|
||||||
|
|
||||||
/* Add the base format load/save operations.
|
|
||||||
*/
|
|
||||||
im__format_init();
|
im__format_init();
|
||||||
|
vips__interpolate_init();
|
||||||
|
|
||||||
/* Load up any plugins in the vips libdir. We don't error on failure,
|
/* 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
|
* 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 *
|
static void *
|
||||||
test_name( VipsObjectClass *class, const char *nickname )
|
test_name( VipsObjectClass *class, const char *nickname )
|
||||||
{
|
{
|
||||||
if( strcasecmp( class->nickname, nickname ) != 0 )
|
if( strcasecmp( class->nickname, nickname ) == 0 )
|
||||||
return( class );
|
return( class );
|
||||||
|
|
||||||
/* Check the class name too, why not.
|
/* 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( class );
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -351,6 +351,20 @@ vips_class_find( const char *basename, const char *nickname )
|
|||||||
return( class );
|
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.
|
/* Like strncpy(), but always NULL-terminate, and don't pad with NULLs.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
|
@ -52,7 +52,49 @@
|
|||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
#endif /*WITH_DMALLOC*/
|
#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,
|
/* Pointers to write to / read from, number of bands,
|
||||||
* how many bytes to add to move down a line.
|
* how many bytes to add to move down a line.
|
||||||
@ -384,9 +426,6 @@ vips_interpolate_bicubic_class_init( VipsInterpolateBicubicClass *iclass )
|
|||||||
VipsInterpolateClass *interpolate_class =
|
VipsInterpolateClass *interpolate_class =
|
||||||
VIPS_INTERPOLATE_CLASS( iclass );
|
VIPS_INTERPOLATE_CLASS( iclass );
|
||||||
|
|
||||||
vips_interpolate_bicubic_parent_class =
|
|
||||||
VIPS_INTERPOLATE_CLASS( g_type_class_peek_parent( iclass ) );
|
|
||||||
|
|
||||||
object_class->nickname = "bicubic";
|
object_class->nickname = "bicubic";
|
||||||
object_class->description = _( "Bicubic interpolation (Catmull-Rom)" );
|
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 )
|
int ox, int oy, int ow, int oh )
|
||||||
{
|
{
|
||||||
return( im_affinei( in, out,
|
return( im_affinei( in, out,
|
||||||
vips_interpolate_bicubic_static(),
|
vips_interpolate_bilinear_static(),
|
||||||
a, b, c, d, dx, dy,
|
a, b, c, d, dx, dy,
|
||||||
ox, oy, ow, oh ) );
|
ox, oy, ow, oh ) );
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,7 @@
|
|||||||
*/
|
*/
|
||||||
#define FLOOR( V ) ((V) >= 0 ? (int)(V) : (int)((V) - 1))
|
#define FLOOR( V ) ((V) >= 0 ? (int)(V) : (int)((V) - 1))
|
||||||
|
|
||||||
static VipsInterpolateClass *vips_interpolate_parent_class = NULL;
|
G_DEFINE_ABSTRACT_TYPE( VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT );
|
||||||
static VipsInterpolateClass *vips_interpolate_nearest_parent_class = NULL;
|
|
||||||
static VipsInterpolateClass *vips_interpolate_bilinear_parent_class = NULL;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void
|
static void
|
||||||
@ -84,8 +82,6 @@ vips_interpolate_class_init( VipsInterpolateClass *class )
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
vips_interpolate_parent_class = g_type_class_peek_parent( class );
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
gobject_class->finalize = vips_interpolate_finalize;
|
gobject_class->finalize = vips_interpolate_finalize;
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
@ -103,31 +99,6 @@ vips_interpolate_init( VipsInterpolate *interpolate )
|
|||||||
#endif /*DEBUG*/
|
#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
|
/* 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.
|
* 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
|
/* 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
|
static void
|
||||||
vips_interpolate_nearest_interpolate( VipsInterpolate *interpolate,
|
vips_interpolate_nearest_interpolate( VipsInterpolate *interpolate,
|
||||||
PEL *out, REGION *in, double x, double y )
|
PEL *out, REGION *in, double x, double y )
|
||||||
@ -191,11 +185,12 @@ vips_interpolate_nearest_interpolate( VipsInterpolate *interpolate,
|
|||||||
static void
|
static void
|
||||||
vips_interpolate_nearest_class_init( VipsInterpolateNearestClass *class )
|
vips_interpolate_nearest_class_init( VipsInterpolateNearestClass *class )
|
||||||
{
|
{
|
||||||
|
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
|
||||||
VipsInterpolateClass *interpolate_class =
|
VipsInterpolateClass *interpolate_class =
|
||||||
VIPS_INTERPOLATE_CLASS( class );
|
VIPS_INTERPOLATE_CLASS( class );
|
||||||
|
|
||||||
vips_interpolate_nearest_parent_class =
|
object_class->nickname = "nearest";
|
||||||
g_type_class_peek_parent( class );
|
object_class->description = _( "Nearest-neighbour interpolation" );
|
||||||
|
|
||||||
interpolate_class->interpolate = vips_interpolate_nearest_interpolate;
|
interpolate_class->interpolate = vips_interpolate_nearest_interpolate;
|
||||||
interpolate_class->window_size = 1;
|
interpolate_class->window_size = 1;
|
||||||
@ -208,32 +203,6 @@ vips_interpolate_nearest_init( VipsInterpolateNearest *nearest )
|
|||||||
printf( "vips_interpolate_nearest_init: " );
|
printf( "vips_interpolate_nearest_init: " );
|
||||||
vips_object_print( VIPS_OBJECT( nearest ) );
|
vips_object_print( VIPS_OBJECT( nearest ) );
|
||||||
#endif /*DEBUG*/
|
#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 *
|
VipsInterpolate *
|
||||||
@ -259,6 +228,38 @@ vips_interpolate_nearest_static( void )
|
|||||||
/* VipsInterpolateBilinear class
|
/* 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.
|
/* in this class, name vars in the 2x2 grid as eg.
|
||||||
* p1 p2
|
* p1 p2
|
||||||
* p3 p4
|
* p3 p4
|
||||||
@ -364,12 +365,13 @@ vips_interpolate_bilinear_interpolate( VipsInterpolate *interpolate,
|
|||||||
static void
|
static void
|
||||||
vips_interpolate_bilinear_class_init( VipsInterpolateBilinearClass *class )
|
vips_interpolate_bilinear_class_init( VipsInterpolateBilinearClass *class )
|
||||||
{
|
{
|
||||||
|
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
|
||||||
VipsInterpolateClass *interpolate_class =
|
VipsInterpolateClass *interpolate_class =
|
||||||
(VipsInterpolateClass *) class;
|
(VipsInterpolateClass *) class;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
vips_interpolate_bilinear_parent_class =
|
object_class->nickname = "bilinear";
|
||||||
g_type_class_peek_parent( class );
|
object_class->description = _( "Bilinear interpolation" );
|
||||||
|
|
||||||
interpolate_class->interpolate = vips_interpolate_bilinear_interpolate;
|
interpolate_class->interpolate = vips_interpolate_bilinear_interpolate;
|
||||||
interpolate_class->window_size = 2;
|
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 *
|
VipsInterpolate *
|
||||||
vips_interpolate_bilinear_new( void )
|
vips_interpolate_bilinear_new( void )
|
||||||
{
|
{
|
||||||
@ -462,3 +439,31 @@ vips_interpolate_bilinear_static( void )
|
|||||||
return( interpolate );
|
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[] = {
|
static im_arg_desc affinei_args[] = {
|
||||||
IM_INPUT_IMAGE( "in" ),
|
IM_INPUT_IMAGE( "in" ),
|
||||||
IM_OUTPUT_IMAGE( "out" ),
|
IM_OUTPUT_IMAGE( "out" ),
|
||||||
IM_INPUT_INT( "interpolate" ),
|
IM_INPUT_STRING( "interpolate" ),
|
||||||
IM_INPUT_DOUBLE( "a" ),
|
IM_INPUT_DOUBLE( "a" ),
|
||||||
IM_INPUT_DOUBLE( "b" ),
|
IM_INPUT_DOUBLE( "b" ),
|
||||||
IM_INPUT_DOUBLE( "c" ),
|
IM_INPUT_DOUBLE( "c" ),
|
||||||
@ -535,46 +535,12 @@ static im_arg_desc affinei_args[] = {
|
|||||||
IM_INPUT_INT( "h" )
|
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.
|
/* Call im_affinei via arg vector.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
affinei_vec( im_object *argv )
|
affinei_vec( im_object *argv )
|
||||||
{
|
{
|
||||||
int interpol = *((int *) argv[2]);
|
const char *interpol = argv[2];
|
||||||
double a = *((double *) argv[3]);
|
double a = *((double *) argv[3]);
|
||||||
double b = *((double *) argv[4]);
|
double b = *((double *) argv[4]);
|
||||||
double c = *((double *) argv[5]);
|
double c = *((double *) argv[5]);
|
||||||
@ -588,7 +554,7 @@ affinei_vec( im_object *argv )
|
|||||||
VipsInterpolate *interpolate;
|
VipsInterpolate *interpolate;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if( !(interpolate = get_interpolate( interpol )) )
|
if( !(interpolate = vips_interpolate_new( interpol )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
result = im_affinei( argv[0], argv[1], interpolate,
|
result = im_affinei( argv[0], argv[1], interpolate,
|
||||||
a, b, c, d, dx, dy, x, y, w, h );
|
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[] = {
|
static im_arg_desc affinei_all_args[] = {
|
||||||
IM_INPUT_IMAGE( "in" ),
|
IM_INPUT_IMAGE( "in" ),
|
||||||
IM_OUTPUT_IMAGE( "out" ),
|
IM_OUTPUT_IMAGE( "out" ),
|
||||||
IM_INPUT_INT( "interpolate" ),
|
IM_INPUT_STRING( "interpolate" ),
|
||||||
IM_INPUT_DOUBLE( "a" ),
|
IM_INPUT_DOUBLE( "a" ),
|
||||||
IM_INPUT_DOUBLE( "b" ),
|
IM_INPUT_DOUBLE( "b" ),
|
||||||
IM_INPUT_DOUBLE( "c" ),
|
IM_INPUT_DOUBLE( "c" ),
|
||||||
@ -627,7 +593,7 @@ static im_arg_desc affinei_all_args[] = {
|
|||||||
static int
|
static int
|
||||||
affinei_all_vec( im_object *argv )
|
affinei_all_vec( im_object *argv )
|
||||||
{
|
{
|
||||||
int interpol = *((int *) argv[2]);
|
const char *interpol = argv[2];
|
||||||
double a = *((double *) argv[3]);
|
double a = *((double *) argv[3]);
|
||||||
double b = *((double *) argv[4]);
|
double b = *((double *) argv[4]);
|
||||||
double c = *((double *) argv[5]);
|
double c = *((double *) argv[5]);
|
||||||
@ -637,7 +603,7 @@ affinei_all_vec( im_object *argv )
|
|||||||
VipsInterpolate *interpolate;
|
VipsInterpolate *interpolate;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if( !(interpolate = get_interpolate( interpol )) )
|
if( !(interpolate = vips_interpolate_new( interpol )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
result = im_affinei_all( argv[0], argv[1], interpolate,
|
result = im_affinei_all( argv[0], argv[1], interpolate,
|
||||||
a, b, c, d, dx, dy );
|
a, b, c, d, dx, dy );
|
||||||
|
@ -50,7 +50,58 @@
|
|||||||
*/
|
*/
|
||||||
#define FLOOR( V ) ((V) >= 0 ? (int)(V) : (int)((V) - 1))
|
#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
|
/* Copy-paste of gegl-sampler-yafr-nohalo.c starts
|
||||||
*/
|
*/
|
||||||
@ -1007,11 +1058,12 @@ vips_interpolate_yafrnohalo_interpolate( VipsInterpolate *interpolate,
|
|||||||
static void
|
static void
|
||||||
vips_interpolate_yafrnohalo_class_init( VipsInterpolateYafrnohaloClass *class )
|
vips_interpolate_yafrnohalo_class_init( VipsInterpolateYafrnohaloClass *class )
|
||||||
{
|
{
|
||||||
|
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
|
||||||
VipsInterpolateClass *interpolate_class =
|
VipsInterpolateClass *interpolate_class =
|
||||||
VIPS_INTERPOLATE_CLASS( class );
|
VIPS_INTERPOLATE_CLASS( class );
|
||||||
|
|
||||||
vips_interpolate_yafrnohalo_parent_class =
|
object_class->nickname = "yafrnohalo";
|
||||||
g_type_class_peek_parent( class );
|
object_class->description = _( "YAFR nohalo interpolation" );
|
||||||
|
|
||||||
interpolate_class->interpolate =
|
interpolate_class->interpolate =
|
||||||
vips_interpolate_yafrnohalo_interpolate;
|
vips_interpolate_yafrnohalo_interpolate;
|
||||||
@ -1028,58 +1080,3 @@ vips_interpolate_yafrnohalo_init( VipsInterpolateYafrnohalo *yafrnohalo )
|
|||||||
|
|
||||||
yafrnohalo->sharpening = 1.0;
|
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)
|
#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
|
/* T is the type of pixels we are computing, D is a type large enough to hold
|
||||||
* (Ta - Tb) ** 2.
|
* (Ta - Tb) ** 2.
|
||||||
@ -668,11 +740,12 @@ vips_interpolate_yafrsmooth_interpolate( VipsInterpolate *interpolate,
|
|||||||
static void
|
static void
|
||||||
vips_interpolate_yafrsmooth_class_init( VipsInterpolateYafrsmoothClass *iclass )
|
vips_interpolate_yafrsmooth_class_init( VipsInterpolateYafrsmoothClass *iclass )
|
||||||
{
|
{
|
||||||
|
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( iclass );
|
||||||
VipsInterpolateClass *interpolate_class =
|
VipsInterpolateClass *interpolate_class =
|
||||||
VIPS_INTERPOLATE_CLASS( iclass );
|
VIPS_INTERPOLATE_CLASS( iclass );
|
||||||
|
|
||||||
vips_interpolate_yafrsmooth_parent_class =
|
object_class->nickname = "yafrsmooth";
|
||||||
VIPS_INTERPOLATE_CLASS( g_type_class_peek_parent( iclass ) );
|
object_class->description = _( "YAFR smooth interpolation" );
|
||||||
|
|
||||||
interpolate_class->interpolate =
|
interpolate_class->interpolate =
|
||||||
vips_interpolate_yafrsmooth_interpolate;
|
vips_interpolate_yafrsmooth_interpolate;
|
||||||
@ -701,59 +774,3 @@ vips_interpolate_yafrsmooth_init( VipsInterpolateYafrsmooth *yafrsmooth )
|
|||||||
|
|
||||||
yafrsmooth->sharpening = 1.0;
|
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
|
* - add input *VEC arg types to C++ binding
|
||||||
* 17/8/08
|
* 17/8/08
|
||||||
* - add --list formats
|
* - add --list formats
|
||||||
|
* 29/11/08
|
||||||
|
* - add --list interpolators
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -164,33 +166,43 @@ list_function( im_function *func )
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
list_format( VipsFormatClass *format )
|
list_format( VipsFormatClass *class )
|
||||||
{
|
{
|
||||||
const char **p;
|
const char **p;
|
||||||
|
|
||||||
printf( "%-20s - ",
|
printf( "%-20s - ",
|
||||||
VIPS_OBJECT_CLASS( format )->description );
|
VIPS_OBJECT_CLASS( class )->description );
|
||||||
|
|
||||||
printf( "(" );
|
printf( "(" );
|
||||||
for( p = format->suffs; *p; p++ ) {
|
for( p = class->suffs; *p; p++ ) {
|
||||||
printf( "%s", *p );
|
printf( "%s", *p );
|
||||||
if( p[1] )
|
if( p[1] )
|
||||||
printf( ", " );
|
printf( ", " );
|
||||||
}
|
}
|
||||||
printf( ") " );
|
printf( ") " );
|
||||||
|
|
||||||
if( format->is_a )
|
if( class->is_a )
|
||||||
printf( "is_a " );
|
printf( "is_a " );
|
||||||
if( format->header )
|
if( class->header )
|
||||||
printf( "header " );
|
printf( "header " );
|
||||||
if( format->load )
|
if( class->load )
|
||||||
printf( "load " );
|
printf( "load " );
|
||||||
if( format->save )
|
if( class->save )
|
||||||
printf( "save " );
|
printf( "save " );
|
||||||
if( format->get_flags )
|
if( class->get_flags )
|
||||||
printf( "get_flags " );
|
printf( "get_flags " );
|
||||||
printf( "\n" );
|
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 );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +213,11 @@ print_list( const char *name )
|
|||||||
im_map_packages( (VSListMap2Fn) list_package, NULL );
|
im_map_packages( (VSListMap2Fn) list_package, NULL );
|
||||||
else if( strcmp( name, "formats" ) == 0 )
|
else if( strcmp( name, "formats" ) == 0 )
|
||||||
vips_format_map( (VSListMap2Fn) list_format, NULL, NULL );
|
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 {
|
else {
|
||||||
if( map_name( name, list_function ) )
|
if( map_name( name, list_function ) )
|
||||||
error_exit( "unknown package \"%s\"", name );
|
error_exit( "unknown package \"%s\"", name );
|
||||||
|
Loading…
Reference in New Issue
Block a user