redo im_convsep() as a class
and im_convsep_f()
This commit is contained in:
parent
edbbc5fe2b
commit
68c5f1909a
@ -1,7 +1,7 @@
|
|||||||
19/10/13 started 7.37.0
|
19/10/13 started 7.37.0
|
||||||
- redone im_rotate_*mask45(), im_gauss_*mask*(), im_log_*mask(), im_dilate(),
|
- redone im_rotate_*mask45(), im_gauss_*mask*(), im_log_*mask(), im_dilate(),
|
||||||
im_erode(), im_rank_image(), im_compass(), im_linedet(), im_gradient()
|
im_erode(), im_rank_image(), im_compass(), im_linedet(), im_gradient(),
|
||||||
as classes
|
im_convsep(), im_convsep_f() as classes
|
||||||
- vips_init() now does some ABI compat checking, though this change requires
|
- vips_init() now does some ABI compat checking, though this change requires
|
||||||
an ABI break
|
an ABI break
|
||||||
- add "interlace" option to vips_jpegsave()
|
- add "interlace" option to vips_jpegsave()
|
||||||
|
10
TODO
10
TODO
@ -1,4 +1,12 @@
|
|||||||
- need to do conv sep
|
- we have aconv and aconvsep
|
||||||
|
|
||||||
|
test timing, make sure it;s worth having a separate aconvsep version
|
||||||
|
|
||||||
|
if it is, make im_aconvsep an optimisation: call im_aconvsep_raw() from
|
||||||
|
vips_conv() if mask width or height == 1 and prec == APPROX
|
||||||
|
|
||||||
|
now we can get rid of im_aconvsep() since it's just vips_convsep() with prec
|
||||||
|
set to approx
|
||||||
|
|
||||||
- do conv and morph quickly as simple wrappers over the vips7 operations
|
- do conv and morph quickly as simple wrappers over the vips7 operations
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ libconvolution_la_SOURCES = \
|
|||||||
convolution.c \
|
convolution.c \
|
||||||
pconvolution.h \
|
pconvolution.h \
|
||||||
conv.c \
|
conv.c \
|
||||||
|
convsep.c \
|
||||||
compass.c \
|
compass.c \
|
||||||
morph.c \
|
morph.c \
|
||||||
convol_dispatch.c \
|
convol_dispatch.c \
|
||||||
|
@ -78,8 +78,8 @@ G_DEFINE_ABSTRACT_TYPE( VipsConvolution, vips_convolution,
|
|||||||
static int
|
static int
|
||||||
vips_convolution_build( VipsObject *object )
|
vips_convolution_build( VipsObject *object )
|
||||||
{
|
{
|
||||||
VipsConvolution *convolution = VIPS_CONVOLUTION( object );
|
|
||||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||||
|
VipsConvolution *convolution = VIPS_CONVOLUTION( object );
|
||||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );
|
VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -149,8 +149,10 @@ vips_convolution_operation_init( void )
|
|||||||
extern int vips_conv_get_type( void );
|
extern int vips_conv_get_type( void );
|
||||||
extern int vips_morph_get_type( void );
|
extern int vips_morph_get_type( void );
|
||||||
extern int vips_compass_get_type( void );
|
extern int vips_compass_get_type( void );
|
||||||
|
extern int vips_convsep_get_type( void );
|
||||||
|
|
||||||
vips_conv_get_type();
|
vips_conv_get_type();
|
||||||
vips_morph_get_type();
|
vips_morph_get_type();
|
||||||
vips_compass_get_type();
|
vips_compass_get_type();
|
||||||
|
vips_convsep_get_type();
|
||||||
}
|
}
|
||||||
|
173
libvips/convolution/convsep.c
Normal file
173
libvips/convolution/convsep.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/* convolve twice, rotating the mask
|
||||||
|
*
|
||||||
|
* 23/10/13
|
||||||
|
* - from vips_convsep()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif /*HAVE_CONFIG_H*/
|
||||||
|
#include <vips/intl.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <vips/vips.h>
|
||||||
|
|
||||||
|
#include "pconvolution.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VipsConvolution parent_instance;
|
||||||
|
|
||||||
|
VipsPrecision precision;
|
||||||
|
int layers;
|
||||||
|
int cluster;
|
||||||
|
} VipsConvsep;
|
||||||
|
|
||||||
|
typedef VipsConvolutionClass VipsConvsepClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsConvsep, vips_convsep, VIPS_TYPE_CONVOLUTION );
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_convsep_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||||
|
VipsConvolution *convolution = (VipsConvolution *) object;
|
||||||
|
VipsConvsep *convsep = (VipsConvsep *) object;
|
||||||
|
VipsImage **t = (VipsImage **)
|
||||||
|
vips_object_local_array( object, 3 );
|
||||||
|
|
||||||
|
g_object_set( convsep, "out", vips_image_new(), NULL );
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_convsep_parent_class )->build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( vips_check_separable( class->nickname, convolution->M ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( vips_rot( convolution->M, &t[0], VIPS_ANGLE_90, NULL ) ||
|
||||||
|
vips_conv( convolution->in, &t[1], convolution->M,
|
||||||
|
"precision", convsep->precision,
|
||||||
|
"layers", convsep->layers,
|
||||||
|
"cluster", convsep->cluster,
|
||||||
|
NULL ) ||
|
||||||
|
vips_conv( t[1], &t[2], t[0],
|
||||||
|
"precision", convsep->precision,
|
||||||
|
"layers", convsep->layers,
|
||||||
|
"cluster", convsep->cluster,
|
||||||
|
NULL ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( vips_image_write( t[2], convolution->out ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_convsep_class_init( VipsConvsepClass *class )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
|
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
object_class->nickname = "convsep";
|
||||||
|
object_class->description = _( "convolution operation" );
|
||||||
|
object_class->build = vips_convsep_build;
|
||||||
|
|
||||||
|
VIPS_ARG_ENUM( class, "precision", 203,
|
||||||
|
_( "Precision" ),
|
||||||
|
_( "Convolve with this precision" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsConvsep, precision ),
|
||||||
|
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "layers", 204,
|
||||||
|
_( "Layers" ),
|
||||||
|
_( "Use this many layers in approximation" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsConvsep, layers ),
|
||||||
|
1, 1000, 5 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "cluster", 205,
|
||||||
|
_( "Cluster" ),
|
||||||
|
_( "Cluster lines closer than this in approximation" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsConvsep, cluster ),
|
||||||
|
1, 100, 1 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_convsep_init( VipsConvsep *convsep )
|
||||||
|
{
|
||||||
|
convsep->precision = VIPS_PRECISION_INTEGER;
|
||||||
|
convsep->layers = 5;
|
||||||
|
convsep->cluster = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_convsep:
|
||||||
|
* @in: input image
|
||||||
|
* @out: output image
|
||||||
|
* @mask: convolution mask
|
||||||
|
*
|
||||||
|
* Optional arguments:
|
||||||
|
*
|
||||||
|
* @precision: calculation accuracy
|
||||||
|
* @layers: number of layers for approximation
|
||||||
|
* @cluster: cluster lines closer than this distance
|
||||||
|
*
|
||||||
|
* Perform a separable convolution of @in with @mask.
|
||||||
|
* See vips_conv() for a detailed description.
|
||||||
|
*
|
||||||
|
* The mask must be 1xn or nx1 elements.
|
||||||
|
*
|
||||||
|
* The image is convolved twice: once with @mask and then again with @mask
|
||||||
|
* rotated by 90 degrees. This is much faster for certain types of mask
|
||||||
|
* (gaussian blur, for example) than doing a full 2D convolution.
|
||||||
|
*
|
||||||
|
* See also: vips_conv(), vips_gaussmat().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_convsep( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start( ap, mask );
|
||||||
|
result = vips_call_split( "convsep", ap, in, out, mask );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
@ -1075,28 +1075,6 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* im_conv:
|
|
||||||
* @in: input image
|
|
||||||
* @out: output image
|
|
||||||
* @mask: convolution mask
|
|
||||||
*
|
|
||||||
* Convolve @in with @mask using integer arithmetic. The output image
|
|
||||||
* always has the same #VipsBandFmt as the input image.
|
|
||||||
*
|
|
||||||
* Each output pixel is
|
|
||||||
* calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
|
|
||||||
* and offset are part of @mask. For integer @in, the division by scale
|
|
||||||
* includes round-to-nearest.
|
|
||||||
*
|
|
||||||
* Convolutions on unsigned 8-bit images are calculated with the
|
|
||||||
* processor's vector unit,
|
|
||||||
* if possible. Disable this with --vips-novector or IM_NOVECTOR.
|
|
||||||
*
|
|
||||||
* See also: im_conv_f(), im_convsep(), im_create_imaskv().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
im_conv( IMAGE *in, IMAGE *out, INTMASK *mask )
|
im_conv( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||||
{
|
{
|
||||||
@ -1114,72 +1092,3 @@ im_conv( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
im_convsep_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|
||||||
{
|
|
||||||
IMAGE *t;
|
|
||||||
INTMASK *rmask;
|
|
||||||
|
|
||||||
if( mask->xsize != 1 && mask->ysize != 1 ) {
|
|
||||||
im_error( "im_convsep",
|
|
||||||
"%s", _( "expect 1xN or Nx1 input mask" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !(t = im_open_local( out, "im_convsep", "p" )) ||
|
|
||||||
!(rmask = (INTMASK *) im_local( out,
|
|
||||||
(im_construct_fn) im_dup_imask,
|
|
||||||
(im_callback_fn) im_free_imask, mask, mask->filename, NULL )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
rmask->xsize = mask->ysize;
|
|
||||||
rmask->ysize = mask->xsize;
|
|
||||||
rmask->offset = 0.;
|
|
||||||
|
|
||||||
if( im_conv_raw( in, t, rmask ) ||
|
|
||||||
im_conv_raw( t, out, mask ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* im_convsep:
|
|
||||||
* @in: input image
|
|
||||||
* @out: output image
|
|
||||||
* @mask: convolution mask
|
|
||||||
*
|
|
||||||
* Perform a separable convolution of @in with @mask using integer arithmetic.
|
|
||||||
* See im_conv() for a detailed description.
|
|
||||||
*
|
|
||||||
* The mask must be 1xn or nx1 elements.
|
|
||||||
* The output image
|
|
||||||
* always has the same #VipsBandFmt as the input image.
|
|
||||||
*
|
|
||||||
* The image is convolved twice: once with @mask and then again with @mask
|
|
||||||
* rotated by 90 degrees. This is much faster for certain types of mask
|
|
||||||
* (gaussian blur, for example) than doing a full 2D convolution.
|
|
||||||
*
|
|
||||||
* See also: im_convsep_f(), im_conv(), im_create_imaskv().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
im_convsep( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|
||||||
{
|
|
||||||
IMAGE *t1 = im_open_local( out, "im_convsep intermediate", "p" );
|
|
||||||
int n_mask = mask->xsize * mask->ysize;
|
|
||||||
|
|
||||||
if( !t1 ||
|
|
||||||
im_embed( in, t1, 1, n_mask / 2, n_mask / 2,
|
|
||||||
in->Xsize + n_mask - 1,
|
|
||||||
in->Ysize + n_mask - 1 ) ||
|
|
||||||
im_convsep_raw( t1, out, mask ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
out->Xoffset = 0;
|
|
||||||
out->Yoffset = 0;
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
@ -392,77 +392,3 @@ im_conv_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|
||||||
{
|
|
||||||
IMAGE *t;
|
|
||||||
DOUBLEMASK *rmask;
|
|
||||||
|
|
||||||
if( mask->xsize != 1 && mask->ysize != 1 ) {
|
|
||||||
im_error( "im_convsep_f",
|
|
||||||
"%s", _( "expect 1xN or Nx1 input mask" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !(t = im_open_local( out, "im_convsep_f", "p" )) ||
|
|
||||||
!(rmask = (DOUBLEMASK *) im_local( out,
|
|
||||||
(im_construct_fn) im_dup_dmask,
|
|
||||||
(im_callback_fn) im_free_dmask, mask, mask->filename, NULL )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
rmask->xsize = mask->ysize;
|
|
||||||
rmask->ysize = mask->xsize;
|
|
||||||
rmask->offset = 0.;
|
|
||||||
|
|
||||||
if( im_conv_f_raw( in, t, rmask ) ||
|
|
||||||
im_conv_f_raw( t, out, mask ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* im_convsep_f:
|
|
||||||
* @in: input image
|
|
||||||
* @out: output image
|
|
||||||
* @mask: convolution mask
|
|
||||||
*
|
|
||||||
* Perform a separable convolution of @in with @mask using floating-point
|
|
||||||
* arithmetic.
|
|
||||||
*
|
|
||||||
* The mask must be 1xn or nx1 elements.
|
|
||||||
* The output image
|
|
||||||
* is always %IM_BANDFMT_FLOAT unless @in is %IM_BANDFMT_DOUBLE, in which case
|
|
||||||
* @out is also %IM_BANDFMT_DOUBLE.
|
|
||||||
*
|
|
||||||
* The image is convolved twice: once with @mask and then again with @mask
|
|
||||||
* rotated by 90 degrees. This is much faster for certain types of mask
|
|
||||||
* (gaussian blur, for example) than doing a full 2D convolution.
|
|
||||||
*
|
|
||||||
* Each output pixel is
|
|
||||||
* calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
|
|
||||||
* and offset are part of @mask.
|
|
||||||
*
|
|
||||||
* See also: im_convsep(), im_conv(), im_create_dmaskv().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
im_convsep_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|
||||||
{
|
|
||||||
IMAGE *t1 = im_open_local( out, "im_convsep intermediate", "p" );
|
|
||||||
int size = mask->xsize * mask->ysize;
|
|
||||||
|
|
||||||
if( !t1 ||
|
|
||||||
im_embed( in, t1, 1, size / 2, size / 2,
|
|
||||||
in->Xsize + size - 1,
|
|
||||||
in->Ysize + size - 1 ) ||
|
|
||||||
im_convsep_f_raw( t1, out, mask ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
out->Xoffset = 0;
|
|
||||||
out->Yoffset = 0;
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
@ -2162,6 +2162,65 @@ im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_convsep_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||||
|
{
|
||||||
|
im_error( "im_convsep_raw", "no compat function" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_convsep( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||||
|
{
|
||||||
|
VipsImage *t1, *t2;
|
||||||
|
|
||||||
|
if( !(t1 = vips_image_new()) ||
|
||||||
|
im_imask2vips( mask, t1 ) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips_convsep( in, &t2, t1,
|
||||||
|
NULL ) ) {
|
||||||
|
g_object_unref( t1 );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
g_object_unref( t1 );
|
||||||
|
if( vips_image_write( t2, out ) ) {
|
||||||
|
g_object_unref( t2 );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
g_object_unref( t2 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_convsep_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
||||||
|
{
|
||||||
|
VipsImage *t1, *t2;
|
||||||
|
|
||||||
|
if( !(t1 = vips_image_new()) ||
|
||||||
|
im_imask2vips( mask, t1 ) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips_convsep( in, &t2, t1,
|
||||||
|
"precision", VIPS_PRECISION_FLOAT,
|
||||||
|
NULL ) ) {
|
||||||
|
g_object_unref( t1 );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
g_object_unref( t1 );
|
||||||
|
if( vips_image_write( t2, out ) ) {
|
||||||
|
g_object_unref( t2 );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
g_object_unref( t2 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips__round( VipsImage *in, VipsImage *out, VipsOperationRound round )
|
vips__round( VipsImage *in, VipsImage *out, VipsOperationRound round )
|
||||||
{
|
{
|
||||||
|
@ -71,6 +71,8 @@ int vips_conv( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
|||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_compass( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
int vips_compass( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
int vips_convsep( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
|
||||||
int vips_morph( VipsImage *in, VipsImage **out, VipsImage *mask,
|
int vips_morph( VipsImage *in, VipsImage **out, VipsImage *mask,
|
||||||
VipsOperationMorphology morph, ... )
|
VipsOperationMorphology morph, ... )
|
||||||
@ -81,12 +83,6 @@ void vips_convolution_operation_init( void );
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int im_aconvsep( VipsImage *in, VipsImage *out,
|
|
||||||
DOUBLEMASK *mask, int n_layers );
|
|
||||||
|
|
||||||
int im_convsep( VipsImage *in, VipsImage *out, INTMASK *mask );
|
|
||||||
int im_convsep_f( VipsImage *in, VipsImage *out, DOUBLEMASK *mask );
|
|
||||||
|
|
||||||
int im_sharpen( VipsImage *in, VipsImage *out,
|
int im_sharpen( VipsImage *in, VipsImage *out,
|
||||||
int mask_size,
|
int mask_size,
|
||||||
double x1, double y2, double y3,
|
double x1, double y2, double y3,
|
||||||
|
@ -88,6 +88,7 @@ int vips_check_vector_length( const char *domain, int n, int len );
|
|||||||
int vips_check_vector( const char *domain, int n, VipsImage *im );
|
int vips_check_vector( const char *domain, int n, VipsImage *im );
|
||||||
int vips_check_hist( const char *domain, VipsImage *im );
|
int vips_check_hist( const char *domain, VipsImage *im );
|
||||||
int vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out );
|
int vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out );
|
||||||
|
int vips_check_separable( const char *domain, VipsImage *im );
|
||||||
|
|
||||||
int vips_check_imask( const char *domain, INTMASK *mask );
|
int vips_check_imask( const char *domain, INTMASK *mask );
|
||||||
int vips_check_dmask( const char *domain, DOUBLEMASK *mask );
|
int vips_check_dmask( const char *domain, DOUBLEMASK *mask );
|
||||||
|
@ -906,6 +906,12 @@ int im_aconv( VipsImage *in, VipsImage *out,
|
|||||||
int im_conv( VipsImage *in, VipsImage *out, INTMASK *mask );
|
int im_conv( VipsImage *in, VipsImage *out, INTMASK *mask );
|
||||||
int im_conv_f( VipsImage *in, VipsImage *out, DOUBLEMASK *mask );
|
int im_conv_f( VipsImage *in, VipsImage *out, DOUBLEMASK *mask );
|
||||||
|
|
||||||
|
int im_aconvsep( VipsImage *in, VipsImage *out,
|
||||||
|
DOUBLEMASK *mask, int n_layers );
|
||||||
|
|
||||||
|
int im_convsep( VipsImage *in, VipsImage *out, INTMASK *mask );
|
||||||
|
int im_convsep_f( VipsImage *in, VipsImage *out, DOUBLEMASK *mask );
|
||||||
|
|
||||||
int im_compass( VipsImage *in, VipsImage *out, INTMASK *mask );
|
int im_compass( VipsImage *in, VipsImage *out, INTMASK *mask );
|
||||||
int im_gradient( VipsImage *in, VipsImage *out, INTMASK *mask );
|
int im_gradient( VipsImage *in, VipsImage *out, INTMASK *mask );
|
||||||
int im_lindetect( VipsImage *in, VipsImage *out, INTMASK *mask );
|
int im_lindetect( VipsImage *in, VipsImage *out, INTMASK *mask );
|
||||||
|
@ -1266,6 +1266,33 @@ vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_check_separable:
|
||||||
|
* @domain: the originating domain for the error message
|
||||||
|
* @im: image to check
|
||||||
|
*
|
||||||
|
* Separable matrix images must have width or height 1.
|
||||||
|
* Return 0 if the image will pass, or -1 and
|
||||||
|
* set an error message otherwise.
|
||||||
|
*
|
||||||
|
* See also: vips_error().
|
||||||
|
*
|
||||||
|
* Returns: 0 if OK, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_check_separable( const char *domain, VipsImage *im )
|
||||||
|
{
|
||||||
|
if( im->Xsize != 1 &&
|
||||||
|
im->Ysize != 1 ) {
|
||||||
|
vips_error( domain,
|
||||||
|
"%s", _( "separable matrix images must have "
|
||||||
|
"width or height 1" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_check_imask: (skip)
|
* vips_check_imask: (skip)
|
||||||
* @domain: the originating domain for the error message
|
* @domain: the originating domain for the error message
|
||||||
|
Loading…
Reference in New Issue
Block a user