From 4d724c00239c53bee80fbe5148df31719e096898 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 24 Oct 2013 08:33:59 +0100 Subject: [PATCH] started compass --- TODO | 3 + libvips/convolution/compass.c | 131 ++++++++++++++++++++++++++++++++++ libvips/convolution/conv.c | 21 +++--- 3 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 libvips/convolution/compass.c diff --git a/TODO b/TODO index d3c45e78..53cadebf 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ +- started compass .. convolution with a rotating mask + + need to do sep - do conv and morph quickly as simple wrappers over the vips7 operations diff --git a/libvips/convolution/compass.c b/libvips/convolution/compass.c new file mode 100644 index 00000000..2553e5e8 --- /dev/null +++ b/libvips/convolution/compass.c @@ -0,0 +1,131 @@ +/* repeatedly convolve with a rotating mask + * + * 23/10/13 + * - from vips_conv() + */ + +/* + + 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 + + */ + +/* This is a simple wrapper over the old vips7 functions. At some point we + * should rewrite this as a pure vips8 class and redo the vips7 functions as + * wrappers over this. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include + +#include + +#include "pconvolution.h" + +typedef struct { + VipsConvolution parent_instance; + + int times; + VipsRotate45 angle; + int join; +} VipsCompass; + +typedef VipsConvolutionClass VipsCompassClass; + +G_DEFINE_TYPE( VipsCompass, vips_compass, VIPS_TYPE_CONVOLUTION ); + +static int +vips_compass_build( VipsObject *object ) +{ + VipsConvolution *convolution = (VipsConvolution *) object; + VipsCompass *compass = (VipsCompass *) object; + + g_object_set( compass, "out", vips_image_new(), NULL ); + + if( VIPS_OBJECT_CLASS( vips_compass_parent_class )->build( object ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_compass_class_init( VipsCompassClass *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 = "compass"; + object_class->description = _( "convolution operation" ); + object_class->build = vips_compass_build; + + VIPS_ARG_ENUM( class, "precision", 103, + _( "Precision" ), + _( "Convolve with this precision" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsCompass, precision ), + VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER ); + + VIPS_ARG_INT( class, "layers", 104, + _( "Layers" ), + _( "Use this many layers in approximation" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsCompass, layers ), + 1, 1000, 5 ); + + VIPS_ARG_INT( class, "cluster", 105, + _( "Cluster" ), + _( "Cluster lines closer than this in approximation" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsCompass, cluster ), + 1, 100, 1 ); + +} + +static void +vips_compass_init( VipsCompass *compass ) +{ + compass->times = 1; + compass->angle = 5; + compass->join = 1; +} + +int +vips_compass( VipsImage *in, VipsImage **out, VipsImage *mask, ... ) +{ + va_list ap; + int result; + + va_start( ap, mask ); + result = vips_call_split( "compass", ap, in, out, mask ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/convolution/conv.c b/libvips/convolution/conv.c index 759b91b8..74d79a76 100644 --- a/libvips/convolution/conv.c +++ b/libvips/convolution/conv.c @@ -62,6 +62,7 @@ G_DEFINE_TYPE( VipsConv, vips_conv, VIPS_TYPE_CONVOLUTION ); static int vips_conv_build( VipsObject *object ) { + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsConvolution *convolution = (VipsConvolution *) object; VipsConv *conv = (VipsConv *) object; @@ -73,27 +74,27 @@ vips_conv_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_conv_parent_class )->build( object ) ) return( -1 ); + if( !(imsk = im_vips2imask( convolution->M, class->nickname )) || + !im_local_imask( convolution->out, imsk ) ) + return( -1 ); + if( !(dmsk = im_vips2mask( convolution->M, class->nickname )) || + !im_local_dmask( convolution->out, dmsk ) ) + return( -1 ); switch( conv->precision ) { case VIPS_PRECISION_INTEGER: - if( !(imsk = im_vips2imask( convolution->M, "im_stats" )) || - !im_local_imask( convolution->out, imsk ) || - im_conv( convolution->in, convolution->out, imsk ) ) + if( im_conv( convolution->in, convolution->out, imsk ) ) return( -1 ); break; case VIPS_PRECISION_FLOAT: - if( !(dmsk = im_vips2mask( convolution->M, "im_stats" )) || - !im_local_dmask( convolution->out, dmsk ) || - im_conv_f( convolution->in, convolution->out, dmsk ) ) + if( im_conv_f( convolution->in, convolution->out, dmsk ) ) return( -1 ); break; case VIPS_PRECISION_APPROXIMATE: - if( !(dmsk = im_vips2mask( convolution->M, "im_stats" )) || - !im_local_dmask( convolution->out, dmsk ) || - im_aconv( convolution->in, convolution->out, dmsk, - conv->layers, conv->cluster ) ) + if( im_aconv( convolution->in, convolution->out, dmsk, + conv->layers, conv->cluster ) ) return( -1 ); break;