From 4bc67b8bee1c2a2bfd820b903c8f4b4d22c10ec9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 4 Jan 2014 13:00:43 +0000 Subject: [PATCH] redo im_disp_ps() as a class --- ChangeLog | 2 +- TODO | 7 +- libvips/deprecated/vips7compat.c | 16 ++++ libvips/freqfilt/Makefile.am | 2 +- libvips/freqfilt/freqfilt.c | 8 ++ libvips/freqfilt/freqmult.c | 9 +- libvips/freqfilt/fwfft.c | 17 +--- libvips/freqfilt/im_disp_ps.c | 108 ---------------------- libvips/freqfilt/invfft.c | 11 +-- libvips/freqfilt/pfreqfilt.h | 3 +- libvips/freqfilt/spectrum.c | 138 +++++++++++++++++++++++++++++ libvips/include/vips/freqfilt.h | 5 +- libvips/include/vips/vips7compat.h | 1 + 13 files changed, 178 insertions(+), 149 deletions(-) delete mode 100644 libvips/freqfilt/im_disp_ps.c create mode 100644 libvips/freqfilt/spectrum.c diff --git a/ChangeLog b/ChangeLog index fbb8f048..9787008c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,7 +32,7 @@ - vipsthumbnail has a --crop option - remove video4linux1 code, it was useless on all modern linuxes - redone freq filter builders as classes -- redone im_fwfft(), im_invfft(), im_freqflt() as classes +- redone im_fwfft(), im_invfft(), im_freqflt(), im_disp_ps() as classes 20/11/13 started 7.36.5 - better cache sizing in unbuffered sequential mode diff --git a/TODO b/TODO index 28f308c1..2d979028 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +- freqfilt almost done + - try: time vips dzsave JP2K-33003-1.svs x --layout zoomify @@ -5,11 +7,6 @@ VIPS:ERROR:buffer.c:390:vips_buffer_new: assertion failed: (!buffer->cache) Aborted (core dumped) -- im_freq_mask.c can almost be deprecated .. just im_freqflt() to do now I - think - - - - new_heart.ws fails with libvips master diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 24aca5fa..2a8fb05a 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -4439,3 +4439,19 @@ im_freqflt( IMAGE *in, IMAGE *mask, IMAGE *out ) return( 0 ); } + +int +im_disp_ps( IMAGE *in, IMAGE *out ) +{ + VipsImage *t; + + if( vips_spectrum( in, &t, NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + return( 0 ); +} diff --git a/libvips/freqfilt/Makefile.am b/libvips/freqfilt/Makefile.am index 9ff706ce..a2a3fcac 100644 --- a/libvips/freqfilt/Makefile.am +++ b/libvips/freqfilt/Makefile.am @@ -6,9 +6,9 @@ libfreqfilt_la_SOURCES = \ fwfft.c \ invfft.c \ freqmult.c \ + spectrum.c \ im_phasecor_fft.c \ freq_dispatch.c \ - im_disp_ps.c \ im_fractsurf.c AM_CPPFLAGS = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ diff --git a/libvips/freqfilt/freqfilt.c b/libvips/freqfilt/freqfilt.c index a705d76f..4124fe99 100644 --- a/libvips/freqfilt/freqfilt.c +++ b/libvips/freqfilt/freqfilt.c @@ -94,6 +94,12 @@ vips_freqfilt_class_init( VipsFreqfiltClass *class ) vobject_class->description = _( "frequency-domain filter operations" ); vobject_class->build = vips_freqfilt_build; + VIPS_ARG_IMAGE( class, "in", -1, + _( "in" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsFreqfilt, in ) ); + VIPS_ARG_IMAGE( class, "out", 1, _( "Output" ), _( "Output image" ), @@ -160,11 +166,13 @@ vips_freqfilt_operation_init( void ) extern GType vips_invfft_get_type( void ); #endif /*HAVE_FFTW*/ extern GType vips_freqmult_get_type( void ); + extern GType vips_spectrum_get_type( void ); #ifdef HAVE_FFTW vips_fwfft_get_type(); vips_invfft_get_type(); #endif /*HAVE_FFTW*/ vips_freqmult_get_type(); + vips_spectrum_get_type(); } diff --git a/libvips/freqfilt/freqmult.c b/libvips/freqfilt/freqmult.c index 07cf610a..01d61bbe 100644 --- a/libvips/freqfilt/freqmult.c +++ b/libvips/freqfilt/freqmult.c @@ -58,7 +58,6 @@ typedef struct _VipsFreqmult { VipsFreqfilt parent_instance; - VipsImage *in; VipsImage *mask; } VipsFreqmult; @@ -79,7 +78,7 @@ vips_freqmult_build( VipsObject *object ) build( object ) ) return( -1 ); - in = freqmult->in; + in = freqfilt->in; if( vips_bandfmt_iscomplex( in->BandFmt ) ) { if( vips_multiply( in, freqmult->mask, &t[0], NULL ) || @@ -128,12 +127,6 @@ vips_freqmult_class_init( VipsFreqmultClass *class ) vobject_class->description = _( "frequency-domain filtering" ); vobject_class->build = vips_freqmult_build; - VIPS_ARG_IMAGE( class, "in", -1, - _( "in" ), - _( "Input image" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsFreqmult, in ) ); - VIPS_ARG_IMAGE( class, "mask", 0, _( "mask" ), _( "Input mask image" ), diff --git a/libvips/freqfilt/fwfft.c b/libvips/freqfilt/fwfft.c index 7120006a..3c9fd8b2 100644 --- a/libvips/freqfilt/fwfft.c +++ b/libvips/freqfilt/fwfft.c @@ -84,7 +84,6 @@ typedef struct _VipsFwfft { VipsFreqfilt parent_instance; - VipsImage *in; } VipsFwfft; typedef VipsFreqfiltClass VipsFwfftClass; @@ -299,13 +298,13 @@ vips_fwfft_build( VipsObject *object ) build( object ) ) return( -1 ); - if( vips_bandfmt_iscomplex( fwfft->in->BandFmt ) ) { - if( vips__fftproc( VIPS_OBJECT( fwfft ), fwfft->in, &t[0], + if( vips_bandfmt_iscomplex( freqfilt->in->BandFmt ) ) { + if( vips__fftproc( VIPS_OBJECT( fwfft ), freqfilt->in, &t[0], cfwfft1 ) ) return( -1 ); } else { - if( vips__fftproc( VIPS_OBJECT( fwfft ), fwfft->in, &t[0], + if( vips__fftproc( VIPS_OBJECT( fwfft ), freqfilt->in, &t[0], rfwfft1 ) ) return( -1 ); } @@ -319,22 +318,12 @@ vips_fwfft_build( VipsObject *object ) static void vips_fwfft_class_init( VipsFwfftClass *class ) { - GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; - vobject_class->nickname = "fwfft"; vobject_class->description = _( "forward FFT" ); vobject_class->build = vips_fwfft_build; - VIPS_ARG_IMAGE( class, "in", 0, - _( "in" ), - _( "Input image" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsFwfft, in ) ); - } static void diff --git a/libvips/freqfilt/im_disp_ps.c b/libvips/freqfilt/im_disp_ps.c deleted file mode 100644 index 6f7e5295..00000000 --- a/libvips/freqfilt/im_disp_ps.c +++ /dev/null @@ -1,108 +0,0 @@ -/* im_disp_ps - * - * Copyright: 1991, N. Dessipris. - * - * Author: Nicos Dessipris - * Written on: 27/03/1991 - * Modified on : - * 16/6/93 J.Cupitt - * - im_ioflag() changed to im_iocheck() - * 23/2/95 JC - * - rewritten for partials - * 10/9/98 JC - * - frees memory more quickly - * 2/4/02 JC - * - any number of bands - * 7/2/10 - * - gtkdoc - * - cleanups - */ - -/* - - 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 -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include - -#include - -static int -disp_ps( IMAGE *dummy, IMAGE *in, IMAGE *out ) -{ - IMAGE *t[3]; - - if( im_open_local_array( out, t, 3, "im_disp_ps temp 1", "p" ) ) - return( -1 ); - - if( in->BandFmt != IM_BANDFMT_COMPLEX ) { - if( im_fwfft( in, t[0] ) ) - return( -1 ); - in = t[0]; - } - - if( im_abs( in, t[1] ) || - im_scaleps( t[1], t[2] ) || - im_rotquad( t[2], out ) ) - return( -1 ); - - return( 0 ); -} - -/** - * im_disp_ps: - * @in: input image - * @out: output image - * - * Make a displayable (ie. 8-bit unsigned int) power spectrum. - * - * If @in is non-complex, it is transformed to Fourier space. Then the - * absolute value is passed through im_scaleps(), and im_rotquad(). - * - * See also: im_scaleps(), im_rotquad(). - * - * Returns: 0 on success, -1 on error. - */ -int -im_disp_ps( IMAGE *in, IMAGE *out ) -{ - IMAGE *dummy; - - if( !(dummy = im_open( "memory:1", "p" )) ) - return( -1 ); - if( disp_ps( dummy, in, out ) ) { - im_close( dummy ); - return( -1 ); - } - im_close( dummy ); - - return( 0 ); -} diff --git a/libvips/freqfilt/invfft.c b/libvips/freqfilt/invfft.c index 49b28ac2..30ea23a9 100644 --- a/libvips/freqfilt/invfft.c +++ b/libvips/freqfilt/invfft.c @@ -73,7 +73,6 @@ typedef struct _VipsInvfft { VipsFreqfilt parent_instance; - VipsImage *in; gboolean real; } VipsInvfft; @@ -214,12 +213,12 @@ vips_invfft_build( VipsObject *object ) if( invfft->real ) { if( vips__fftproc( VIPS_OBJECT( invfft ), - invfft->in, &t[0], rinvfft1 ) ) + freqfilt->in, &t[0], rinvfft1 ) ) return( -1 ); } else { if( vips__fftproc( VIPS_OBJECT( invfft ), - invfft->in, &t[0], cinvfft1 ) ) + freqfilt->in, &t[0], cinvfft1 ) ) return( -1 ); } @@ -242,12 +241,6 @@ vips_invfft_class_init( VipsInvfftClass *class ) vobject_class->description = _( "inverse FFT" ); vobject_class->build = vips_invfft_build; - VIPS_ARG_IMAGE( class, "in", 0, - _( "in" ), - _( "Input image" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsInvfft, in ) ); - VIPS_ARG_BOOL( class, "real", 4, _( "Real" ), _( "Ouput only the real part of the transform" ), diff --git a/libvips/freqfilt/pfreqfilt.h b/libvips/freqfilt/pfreqfilt.h index 30e1ba31..d1e60694 100644 --- a/libvips/freqfilt/pfreqfilt.h +++ b/libvips/freqfilt/pfreqfilt.h @@ -55,8 +55,7 @@ extern "C" { typedef struct _VipsFreqfilt { VipsOperation parent_instance; - /* All have an output image. - */ + VipsImage *in; VipsImage *out; } VipsFreqfilt; diff --git a/libvips/freqfilt/spectrum.c b/libvips/freqfilt/spectrum.c new file mode 100644 index 00000000..685c4109 --- /dev/null +++ b/libvips/freqfilt/spectrum.c @@ -0,0 +1,138 @@ +/* make a displayable power spectrum for an image + * + * Author: Nicos Dessipris + * Written on: 27/03/1991 + * Modified on : + * 16/6/93 J.Cupitt + * - im_ioflag() changed to im_iocheck() + * 23/2/95 JC + * - rewritten for partials + * 10/9/98 JC + * - frees memory more quickly + * 2/4/02 JC + * - any number of bands + * 7/2/10 + * - gtkdoc + * - cleanups + * 3/1/14 + * - redone as a class + */ + +/* + + 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 +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include + +#include +#include "pfreqfilt.h" + +typedef VipsFreqfilt VipsSpectrum; +typedef VipsFreqfiltClass VipsSpectrumClass; + +G_DEFINE_TYPE( VipsSpectrum, vips_spectrum, VIPS_TYPE_FREQFILT ); + +static int +vips_spectrum_build( VipsObject *object ) +{ + VipsFreqfilt *freqfilt = VIPS_FREQFILT( object ); + VipsImage **t = (VipsImage **) vips_object_local_array( object, 5 ); + + VipsImage *in; + + if( VIPS_OBJECT_CLASS( vips_spectrum_parent_class )-> + build( object ) ) + return( -1 ); + + in = freqfilt->in; + + if( in->BandFmt != VIPS_FORMAT_COMPLEX ) { + if( vips_fwfft( in, &t[0], NULL ) ) + return( -1 ); + in = t[0]; + } + + if( vips_abs( in, &t[1], NULL ) || + vips_scale( t[1], &t[2], "log", TRUE, NULL ) || + vips_wrap( t[2], &t[3], NULL ) ) + return( -1 ); + + if( vips_image_write( t[3], freqfilt->out ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_spectrum_class_init( VipsSpectrumClass *class ) +{ + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + + vobject_class->nickname = "spectrum"; + vobject_class->description = _( "make displayable power spectrum" ); + vobject_class->build = vips_spectrum_build; + +} + +static void +vips_spectrum_init( VipsSpectrum *spectrum ) +{ +} + +/** + * vips_spectrum: + * @in: input image + * @out: output image + * @...: %NULL-terminated list of optional named arguments + * + * Make a displayable (ie. 8-bit unsigned int) power spectrum. + * + * If @in is non-complex, it is transformed to Fourier space. Then the + * absolute value is passed through vips_scale() in log mode, and vips_wrap(). + * + * See also: vips_fwfft(), vips_scale(), vips_wrap(). + * + * Returns: 0 on success, -1 on error. + */ +int +vips_spectrum( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "spectrum", ap, in, out ); + va_end( ap ); + + return( result ); +} + diff --git a/libvips/include/vips/freqfilt.h b/libvips/include/vips/freqfilt.h index 242f68ec..a1d42479 100644 --- a/libvips/include/vips/freqfilt.h +++ b/libvips/include/vips/freqfilt.h @@ -42,10 +42,13 @@ int vips_fwfft( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_invfft( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); + int vips_freqmult( VipsImage *in, VipsImage *mask, VipsImage **out, ... ) __attribute__((sentinel)); -int im_disp_ps( VipsImage *in, VipsImage *out ); +int vips_spectrum( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); + int im_phasecor_fft( VipsImage *in1, VipsImage *in2, VipsImage *out ); int im_fractsurf( VipsImage *out, int size, double frd ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index a34a70ae..63bb4c94 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -971,6 +971,7 @@ int im_invfft( VipsImage *in, VipsImage *out ); int im_invfftr( VipsImage *in, VipsImage *out ); int im_freqflt( VipsImage *in, VipsImage *mask, VipsImage *out ); +int im_disp_ps( VipsImage *in, VipsImage *out ); #ifdef __cplusplus }