From 187212768d785f5cac0e81cf8d9a0d99e1cfdc3b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 19 Nov 2011 11:24:04 +0000 Subject: [PATCH] add class for complex ops and it does conj as well --- ChangeLog | 4 +- TODO | 15 +- libvips/arithmetic/Makefile.am | 1 + libvips/arithmetic/arithmetic.c | 2 + libvips/arithmetic/complex.c | 331 +++++++++++++++++++++++++++++ libvips/conversion/Makefile.am | 2 - libvips/conversion/cast.c | 40 ++-- libvips/conversion/im_c2amph.c | 120 ----------- libvips/conversion/im_c2rect.c | 109 ---------- libvips/deprecated/vips7compat.c | 29 +++ libvips/include/vips/arithmetic.h | 25 +++ libvips/include/vips/conversion.h | 26 +-- libvips/include/vips/enumtypes.h | 2 + libvips/include/vips/vips7compat.h | 3 + libvips/iofuncs/enumtypes.c | 19 ++ 15 files changed, 463 insertions(+), 265 deletions(-) create mode 100644 libvips/arithmetic/complex.c delete mode 100644 libvips/conversion/im_c2amph.c delete mode 100644 libvips/conversion/im_c2rect.c diff --git a/ChangeLog b/ChangeLog index 076a0680..9e3c92fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,7 +11,7 @@ im_multiply(), im_stats(), im_measure(), im_recomb(), im_floor(), im_ceil(), im_rint(), im_equal*(), im_notequal*(), im_less*(), im_lesseq*(), im_more*(), im_moreeq*(), im_remainder*(), im_and*(), im_or*(), im_eor*(), im_shift*(), - im_pow*(), im_exp*(), im_ifthenelse(), im_blend() + im_pow*(), im_exp*(), im_ifthenelse(), im_blend(), im_c2amph(), im_c2rect() redone as classes - added argument priorites to help control arg ordering - generate has a 'stop' param to signal successful early termination @@ -47,6 +47,8 @@ - use atexit() to call vips_shutdown() - set _O_TEMPORARY on delete-on-close temp images if possible - unlink temps on rewind on *nix, less likely to leave temps on a crash +- added complex conj as a basic operation +- rect/polar/conj work o any format, not just complex 12/10/11 started 7.26.6 - NOCACHE was not being set correctly on OS X causing performance diff --git a/TODO b/TODO index e334624b..f3b7e53a 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,19 @@ - test docs - do relational.c next + do polar.c + + do we need a VipsUnary subclass for complex? needs to cast input to complex + before it starts + + do polar/rectangular/conjugate in it + + or maybe have a single thing with an enum for complex ops lke this + + + +- look at the help message from the vips-7.27 script + + try diff --git a/libvips/arithmetic/Makefile.am b/libvips/arithmetic/Makefile.am index 96eb7b22..62443355 100644 --- a/libvips/arithmetic/Makefile.am +++ b/libvips/arithmetic/Makefile.am @@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libarithmetic.la libarithmetic_la_SOURCES = \ arith_dispatch.c \ abs.c \ + complex.c \ im_bandmean.c \ im_cross_phase.c \ deviate.c \ diff --git a/libvips/arithmetic/arithmetic.c b/libvips/arithmetic/arithmetic.c index bf8d4bfa..bdb130a3 100644 --- a/libvips/arithmetic/arithmetic.c +++ b/libvips/arithmetic/arithmetic.c @@ -503,6 +503,7 @@ vips_arithmetic_operation_init( void ) extern GType vips_boolean_const_get_type( void ); extern GType vips_math2_get_type( void ); extern GType vips_math2_const_get_type( void ); + extern GType vips_complex_get_type( void ); vips_add_get_type(); vips_subtract_get_type(); @@ -529,4 +530,5 @@ vips_arithmetic_operation_init( void ) vips_boolean_const_get_type(); vips_math2_get_type(); vips_math2_const_get_type(); + vips_complex_get_type(); } diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c new file mode 100644 index 00000000..9b3fd2ce --- /dev/null +++ b/libvips/arithmetic/complex.c @@ -0,0 +1,331 @@ +/* complex.c ... various complex operations + * + * Copyright: 1990, N. Dessipris. + * + * Author: Nicos Dessipris + * Written on: 12/02/1990 + * Modified on : 09/05/1990 + * 15/6/93 JC + * - stupid stupid includes and externs fixed + * - I have been editing for 1 1/2 hours and I'm still drowning in + * rubbish extetrnshh + * 13/12/94 JC + * - modernised + * 9/7/02 JC + * - degree output, for consistency + * - slightly better behaviour in edge cases + * 27/1/10 + * - modernised + * - gtk-doc + * 19/11/11 + * - redo as a class + */ + +/* + + Copyright (C) 1991-2005 The National Gallery + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU 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 + + */ + +/* +#define DEBUG + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include +#include + +#include + +#include "unary.h" + +typedef struct _VipsComplex { + VipsUnary parent_instance; + + VipsOperationComplex cmplx; + +} VipsComplex; + +typedef VipsUnaryClass VipsComplexClass; + +G_DEFINE_TYPE( VipsComplex, vips_complex, VIPS_TYPE_UNARY ); + +#define LOOP( IN, OUT, OP ) { \ + IN *p = (IN *) in[0]; \ + OUT *q = (OUT *) out; \ + \ + for( x = 0; x < sz; x++ ) { \ + OP( q, p[x], 0.0 ); \ + \ + q += 2; \ + } \ +} + +#define CLOOP( IN, OUT, OP ) { \ + IN *p = (IN *) in[0]; \ + OUT *q = (OUT *) out; \ + \ + for( x = 0; x < sz; x++ ) { \ + OP( q, p[0], p[1] ); \ + \ + p += 2; \ + q += 2; \ + } \ +} + +#define SWITCH( OP ) \ + switch( vips_image_get_format( im ) ) { \ + case VIPS_FORMAT_UCHAR: \ + LOOP( unsigned char, float, OP ); break; \ + case VIPS_FORMAT_CHAR: \ + LOOP( signed char, float, OP ); break; \ + case VIPS_FORMAT_USHORT: \ + LOOP( unsigned short, float, OP ); break; \ + case VIPS_FORMAT_SHORT: \ + LOOP( signed short, float, OP ); break; \ + case VIPS_FORMAT_UINT: \ + LOOP( unsigned int, float, OP ); break; \ + case VIPS_FORMAT_INT: \ + LOOP( signed int, float, OP ); break; \ + case VIPS_FORMAT_FLOAT: \ + LOOP( float, float, OP ); break; \ + case VIPS_FORMAT_DOUBLE: \ + LOOP( double, double, OP ); break;\ + case VIPS_FORMAT_COMPLEX: \ + CLOOP( float, float, OP ); break; \ + case VIPS_FORMAT_DPCOMPLEX: \ + CLOOP( double, double, OP ); break;\ + \ + default: \ + g_assert( 0 ); \ + } + +#define POLAR( Q, X, Y ) { \ + double re = (X); \ + double im = (Y); \ + double am, ph; \ + \ + am = sqrt( re * re + im * im ); \ + ph = im_col_ab2h( re, im ); \ + \ + Q[0] = am; \ + Q[1] = ph; \ +} + +#define RECT( Q, X, Y ) { \ + double am = (X); \ + double ph = (Y); \ + double re, im; \ + \ + re = am * cos( VIPS_RAD( ph ) ); \ + im = am * sin( VIPS_RAD( ph ) ); \ + \ + Q[0] = re; \ + Q[1] = im; \ +} + +#define CONJ( Q, X, Y ) { \ + double re = (X); \ + double im = (Y); \ + \ + im *= -1; \ + \ + Q[0] = re; \ + Q[1] = im; \ +} + +static void +vips_complex_buffer( VipsArithmetic *arithmetic, PEL *out, PEL **in, int width ) +{ + VipsComplex *cmplx = (VipsComplex *) arithmetic; + VipsImage *im = arithmetic->ready[0]; + const int sz = width * vips_image_get_bands( im ); + + int x; + + switch( cmplx->cmplx ) { + case VIPS_OPERATION_COMPLEX_POLAR: SWITCH( POLAR ); break; + case VIPS_OPERATION_COMPLEX_RECT: SWITCH( RECT ); break; + case VIPS_OPERATION_COMPLEX_CONJ: SWITCH( CONJ ); break; + + default: + g_assert( 0 ); + } +} + +/* Save a bit of typing. + */ +#define UC VIPS_FORMAT_UCHAR +#define C VIPS_FORMAT_CHAR +#define US VIPS_FORMAT_USHORT +#define S VIPS_FORMAT_SHORT +#define UI VIPS_FORMAT_UINT +#define I VIPS_FORMAT_INT +#define F VIPS_FORMAT_FLOAT +#define X VIPS_FORMAT_COMPLEX +#define D VIPS_FORMAT_DOUBLE +#define DX VIPS_FORMAT_DPCOMPLEX + +static const VipsBandFormat vips_bandfmt_complex[10] = { +/* UC C US S UI I F X D DX */ + X, X, X, X, X, X, X, X, DX, DX +}; + +static void +vips_complex_class_init( VipsComplexClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + object_class->nickname = "complex"; + object_class->description = + _( "perform a complex operation on an image" ); + + vips_arithmetic_set_format_table( aclass, vips_bandfmt_complex ); + + aclass->process_line = vips_complex_buffer; + + VIPS_ARG_ENUM( class, "cmplx", 200, + _( "Operation" ), + _( "complex to perform" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsComplex, cmplx ), + VIPS_TYPE_OPERATION_COMPLEX, VIPS_OPERATION_COMPLEX_POLAR ); +} + +static void +vips_complex_init( VipsComplex *complex ) +{ +} + +static int +vips_complexv( VipsImage *in, VipsImage **out, + VipsOperationComplex cmplx, va_list ap ) +{ + return( vips_call_split( "complex", ap, in, out, cmplx ) ); +} + +/** + * vips_complex: + * @in: input #VipsImage + * @out: output #VipsImage + * @cmplx: complex operation to perform + * @...: %NULL-terminated list of optional named arguments + * + * Perform various operations on complex images. + * + * Angles are expressed in degrees. The output type is complex unless the + * input is double or dpcomplex, in which case the output is dpcomplex. + * + * Returns: 0 on success, -1 on error + */ +int +vips_complex( VipsImage *in, VipsImage **out, VipsOperationComplex cmplx, ... ) +{ + va_list ap; + int result; + + va_start( ap, cmplx ); + result = vips_complexv( in, out, cmplx, ap ); + va_end( ap ); + + return( result ); +} + +/** + * vips_polar: + * @in: input #VipsImage + * @out: output #VipsImage + * @...: %NULL-terminated list of optional named arguments + * + * Perform #VIPS_OPERATION_COMPLEX_POLAR on an image. See vips_complex(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_polar( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_complexv( in, out, VIPS_OPERATION_COMPLEX_POLAR, ap ); + va_end( ap ); + + return( result ); +} + +/** + * vips_rect: + * @in: input #VipsImage + * @out: output #VipsImage + * @...: %NULL-terminated list of optional named arguments + * + * Perform #VIPS_OPERATION_COMPLEX_RECT on an image. See vips_complex(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_rect( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_complexv( in, out, VIPS_OPERATION_COMPLEX_POLAR, ap ); + va_end( ap ); + + return( result ); +} + +/** + * vips_conj: + * @in: input #VipsImage + * @out: output #VipsImage + * @...: %NULL-terminated list of optional named arguments + * + * Perform #VIPS_OPERATION_COMPLEX_CONJ on an image. See vips_complex(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_conj( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_complexv( in, out, VIPS_OPERATION_COMPLEX_CONJ, ap ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/conversion/Makefile.am b/libvips/conversion/Makefile.am index e4556bd1..5e49d8b1 100644 --- a/libvips/conversion/Makefile.am +++ b/libvips/conversion/Makefile.am @@ -16,8 +16,6 @@ libconversion_la_SOURCES = \ rot.c \ ifthenelse.c \ conver_dispatch.c \ - im_c2amph.c \ - im_c2rect.c \ im_c2imag.c \ im_c2real.c \ im_copy_file.c \ diff --git a/libvips/conversion/cast.c b/libvips/conversion/cast.c index 4b6fa7cf..cd9d61f7 100644 --- a/libvips/conversion/cast.c +++ b/libvips/conversion/cast.c @@ -526,7 +526,7 @@ vips_cast( VipsImage *in, VipsImage **out, VipsBandFormat format, ... ) } /** - * vips_uchar: + * vips_cast_uchar: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -536,7 +536,7 @@ vips_cast( VipsImage *in, VipsImage **out, VipsBandFormat format, ... ) * Returns: 0 on success, -1 on error */ int -vips_uchar( VipsImage *in, VipsImage **out, ... ) +vips_cast_uchar( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -549,7 +549,7 @@ vips_uchar( VipsImage *in, VipsImage **out, ... ) } /** - * vips_char: + * vips_cast_char: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -559,7 +559,7 @@ vips_uchar( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_char( VipsImage *in, VipsImage **out, ... ) +vips_cast_char( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -572,7 +572,7 @@ vips_char( VipsImage *in, VipsImage **out, ... ) } /** - * vips_ushort: + * vips_cast_ushort: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -582,7 +582,7 @@ vips_char( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_ushort( VipsImage *in, VipsImage **out, ... ) +vips_cast_ushort( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -595,7 +595,7 @@ vips_ushort( VipsImage *in, VipsImage **out, ... ) } /** - * vips_short: + * vips_cast_short: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -605,7 +605,7 @@ vips_ushort( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_short( VipsImage *in, VipsImage **out, ... ) +vips_cast_short( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -618,7 +618,7 @@ vips_short( VipsImage *in, VipsImage **out, ... ) } /** - * vips_uint: + * vips_cast_uint: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -628,7 +628,7 @@ vips_short( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_uint( VipsImage *in, VipsImage **out, ... ) +vips_cast_uint( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -641,7 +641,7 @@ vips_uint( VipsImage *in, VipsImage **out, ... ) } /** - * vips_int: + * vips_cast_int: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -651,7 +651,7 @@ vips_uint( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_int( VipsImage *in, VipsImage **out, ... ) +vips_cast_int( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -664,7 +664,7 @@ vips_int( VipsImage *in, VipsImage **out, ... ) } /** - * vips_float: + * vips_cast_float: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -674,7 +674,7 @@ vips_int( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_float( VipsImage *in, VipsImage **out, ... ) +vips_cast_float( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -687,7 +687,7 @@ vips_float( VipsImage *in, VipsImage **out, ... ) } /** - * vips_double: + * vips_cast_double: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -697,7 +697,7 @@ vips_float( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_double( VipsImage *in, VipsImage **out, ... ) +vips_cast_double( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -710,7 +710,7 @@ vips_double( VipsImage *in, VipsImage **out, ... ) } /** - * vips_complex: + * vips_cast_complex: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -720,7 +720,7 @@ vips_double( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_complex( VipsImage *in, VipsImage **out, ... ) +vips_cast_complex( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; @@ -733,7 +733,7 @@ vips_complex( VipsImage *in, VipsImage **out, ... ) } /** - * vips_dpcomplex: + * vips_cast_dpcomplex: * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments @@ -743,7 +743,7 @@ vips_complex( VipsImage *in, VipsImage **out, ... ) * Returns: 0 on success, -1 on error */ int -vips_dpcomplex( VipsImage *in, VipsImage **out, ... ) +vips_cast_dpcomplex( VipsImage *in, VipsImage **out, ... ) { va_list ap; int result; diff --git a/libvips/conversion/im_c2amph.c b/libvips/conversion/im_c2amph.c deleted file mode 100644 index bd49af0c..00000000 --- a/libvips/conversion/im_c2amph.c +++ /dev/null @@ -1,120 +0,0 @@ -/* im_c2amph.c ... convert to polar - * - * Copyright: 1990, N. Dessipris. - * - * Author: Nicos Dessipris - * Written on: 12/02/1990 - * Modified on : 09/05/1990 - * 15/6/93 JC - * - stupid stupid includes and externs fixed - * - I have been editing for 1 1/2 hours and I'm still drowning in - * rubbish extetrnshh - * 13/12/94 JC - * - modernised - * 9/7/02 JC - * - degree output, for consistency - * - slightly better behaviour in edge cases - * 27/1/10 - * - modernised - * - gtk-doc - */ - -/* - - 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 - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include -#include - -#include - -#define loop(TYPE) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - int x; \ - \ - for( x = 0; x < n; x++ ) { \ - double re = p[0]; \ - double im = p[1]; \ - double am, ph; \ - \ - am = sqrt( re * re + im * im ); \ - ph = im_col_ab2h( re, im ); \ - \ - q[0] = am; \ - q[1] = ph; \ - \ - p += 2; \ - q += 2; \ - } \ -} - -/* c2amph buffer processor. - */ -static void -buffer_c2amph( void *in, void *out, int w, IMAGE *im ) -{ - int n = w * im->Bands; - - switch( im->BandFmt ) { - case IM_BANDFMT_DPCOMPLEX: loop(double); break; - case IM_BANDFMT_COMPLEX: loop(float); break; - default: - g_assert( 0 ); - } -} - -/** - * im_c2amph: - * @in: input image - * @out: output image - * - * Convert a complex image from rectangular to polar coordinates. Angles are - * expressed in degrees. - * - * See also: im_c2rect(), im_abs(). - * - * Returns: 0 on success, -1 on error - */ -int -im_c2amph( IMAGE *in, IMAGE *out ) -{ - if( im_check_uncoded( "im_c2amph", in ) || - im_check_complex( "im_c2amph", in ) || - im_cp_desc( out, in ) ) - return( -1 ); - - if( im_wrapone( in, out, - (im_wrapone_fn) buffer_c2amph, in, NULL ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/conversion/im_c2rect.c b/libvips/conversion/im_c2rect.c deleted file mode 100644 index bc088695..00000000 --- a/libvips/conversion/im_c2rect.c +++ /dev/null @@ -1,109 +0,0 @@ -/* im_c2rect.c ... convert polar to rectangular - * - * 9/7/02 JC - * - from im_c2amph() - * 27/1/10 - * - modernised - * - gtk-doc - */ - -/* - - 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 - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include -#include - -#include - -#define loop(TYPE) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - int x; \ - \ - for( x = 0; x < n; x++ ) { \ - double am = p[0]; \ - double ph = p[1]; \ - double re, im; \ - \ - re = am * cos( IM_RAD( ph ) ); \ - im = am * sin( IM_RAD( ph ) ); \ - \ - q[0] = re; \ - q[1] = im; \ - \ - p += 2; \ - q += 2; \ - } \ -} - -/* c2rect buffer processor. - */ -static void -buffer_c2rect( void *in, void *out, int w, IMAGE *im ) -{ - int n = w * im->Bands; - - switch( im->BandFmt ) { - case IM_BANDFMT_DPCOMPLEX: loop(double); break; - case IM_BANDFMT_COMPLEX: loop(float); break; - default: - g_assert( 0 ); - } -} - - -/** - * im_c2rect: - * @in: input image - * @out: output image - * - * Convert a complex image from polar to rectangular coordinates. Angles are - * expressed in degrees. - * - * See also: im_c2amph(). - * - * Returns: 0 on success, -1 on error - */ -int -im_c2rect( IMAGE *in, IMAGE *out ) -{ - if( im_check_uncoded( "im_c2rect", in ) || - im_check_complex( "im_c2rect", in ) || - im_cp_desc( out, in ) ) - return( -1 ); - - if( im_wrapone( in, out, - (im_wrapone_fn) buffer_c2rect, in, NULL ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 4c364704..3e4c8215 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2076,3 +2076,32 @@ im_blend( VipsImage *c, VipsImage *a, VipsImage *b, VipsImage *out ) return( 0 ); } + +static int +vips__complex( VipsImage *in, VipsImage *out, VipsOperationComplex cmplx ) +{ + VipsImage *t; + + if( vips_complex( in, &t, cmplx, + NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + return( 0 ); +} + +int +im_c2amph( IMAGE *in, IMAGE *out ) +{ + return( vips__complex( in, out, VIPS_OPERATION_COMPLEX_POLAR ) ); +} + +int +im_c2rect( IMAGE *in, IMAGE *out ) +{ + return( vips__complex( in, out, VIPS_OPERATION_COMPLEX_RECT ) ); +} diff --git a/libvips/include/vips/arithmetic.h b/libvips/include/vips/arithmetic.h index 3cd2f8cb..86103b61 100644 --- a/libvips/include/vips/arithmetic.h +++ b/libvips/include/vips/arithmetic.h @@ -132,6 +132,21 @@ typedef enum { VIPS_OPERATION_BOOLEAN_LAST } VipsOperationBoolean; +/** + * VipsOperationComplex: + * @VIPS_OPERATION_COMPLEX_POLAR: convert to polar coordinates + * @VIPS_OPERATION_COMPLEX_RECT: convert to rectangular coordinates + * @VIPS_OPERATION_COMPLEX_CONJ: complex conjugate + * + * See also: vips_complex(). + */ +typedef enum { + VIPS_OPERATION_COMPLEX_POLAR, + VIPS_OPERATION_COMPLEX_RECT, + VIPS_OPERATION_COMPLEX_CONJ, + VIPS_OPERATION_COMPLEX_LAST +} VipsOperationComplex; + int vips_add( VipsImage *left, VipsImage *right, VipsImage **out, ... ) __attribute__((sentinel)); int vips_subtract( VipsImage *in1, VipsImage *in2, VipsImage **out, ... ) @@ -192,6 +207,16 @@ int vips_log( VipsImage *in, VipsImage **out, ... ) int vips_log10( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); +int vips_complex( VipsImage *in, VipsImage **out, + VipsOperationComplex cmplx, ... ) + __attribute__((sentinel)); +int vips_polar( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); +int vips_rect( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); +int vips_conj( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); + int vips_relational( VipsImage *left, VipsImage *right, VipsImage **out, VipsOperationRelational relational, ... ) __attribute__((sentinel)); diff --git a/libvips/include/vips/conversion.h b/libvips/include/vips/conversion.h index fefcf61e..b1ecd50d 100644 --- a/libvips/include/vips/conversion.h +++ b/libvips/include/vips/conversion.h @@ -158,25 +158,25 @@ int vips_replicate( VipsImage *in, VipsImage **out, int across, int down, ... ) int vips_cast( VipsImage *in, VipsImage **out, VipsBandFormat format, ... ) __attribute__((sentinel)); -int vips_uchar( VipsImage *in, VipsImage **out, ... ) +int vips_cast_uchar( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_char( VipsImage *in, VipsImage **out, ... ) +int vips_cast_char( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_ushort( VipsImage *in, VipsImage **out, ... ) +int vips_cast_ushort( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_short( VipsImage *in, VipsImage **out, ... ) +int vips_cast_short( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_uint( VipsImage *in, VipsImage **out, ... ) +int vips_cast_uint( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_int( VipsImage *in, VipsImage **out, ... ) +int vips_cast_int( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_float( VipsImage *in, VipsImage **out, ... ) +int vips_cast_float( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_double( VipsImage *in, VipsImage **out, ... ) +int vips_cast_double( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_complex( VipsImage *in, VipsImage **out, ... ) +int vips_cast_complex( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); -int vips_dpcomplex( VipsImage *in, VipsImage **out, ... ) +int vips_cast_dpcomplex( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_bandjoin( VipsImage **in, VipsImage **out, int n, ... ) @@ -192,14 +192,16 @@ int vips_ifthenelse( VipsImage *cond, VipsImage *in1, VipsImage *in2, __attribute__((sentinel)); + + + + int im_copy_file( VipsImage *in, VipsImage *out ); int im_scale( VipsImage *in, VipsImage *out ); int im_msb( VipsImage *in, VipsImage *out ); int im_msb_band( VipsImage *in, VipsImage *out, int band ); -int im_c2amph( VipsImage *in, VipsImage *out ); -int im_c2rect( VipsImage *in, VipsImage *out ); int im_ri2c( VipsImage *in1, VipsImage *in2, VipsImage *out ); int im_c2imag( VipsImage *in, VipsImage *out ); int im_c2real( VipsImage *in, VipsImage *out ); diff --git a/libvips/include/vips/enumtypes.h b/libvips/include/vips/enumtypes.h index 3a0b8985..6842ce1e 100644 --- a/libvips/include/vips/enumtypes.h +++ b/libvips/include/vips/enumtypes.h @@ -17,6 +17,8 @@ GType vips_operation_relational_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_OPERATION_RELATIONAL (vips_operation_relational_get_type()) GType vips_operation_boolean_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_OPERATION_BOOLEAN (vips_operation_boolean_get_type()) +GType vips_operation_complex_get_type (void) G_GNUC_CONST; +#define VIPS_TYPE_OPERATION_COMPLEX (vips_operation_complex_get_type()) /* enumerations from "../../../libvips/include/vips/conversion.h" */ GType vips_extend_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_EXTEND (vips_extend_get_type()) diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index ed0f1eb4..69558c98 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -631,6 +631,9 @@ int im_bandjoin( VipsImage *in1, VipsImage *in2, VipsImage *out ); int im_gbandjoin( VipsImage **in, VipsImage *out, int n ); int im_black( VipsImage *out, int x, int y, int bands ); +int im_c2amph( VipsImage *in, VipsImage *out ); +int im_c2rect( VipsImage *in, VipsImage *out ); + int im_rot90( VipsImage *in, VipsImage *out ); int im_rot180( VipsImage *in, VipsImage *out ); int im_rot270( VipsImage *in, VipsImage *out ); diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index d7ca08e3..5a21989c 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -190,6 +190,25 @@ vips_operation_boolean_get_type( void ) return( etype ); } +GType +vips_operation_complex_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_COMPLEX_POLAR, "VIPS_OPERATION_COMPLEX_POLAR", "polar"}, + {VIPS_OPERATION_COMPLEX_RECT, "VIPS_OPERATION_COMPLEX_RECT", "rect"}, + {VIPS_OPERATION_COMPLEX_CONJ, "VIPS_OPERATION_COMPLEX_CONJ", "conj"}, + {VIPS_OPERATION_COMPLEX_LAST, "VIPS_OPERATION_COMPLEX_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationComplex", values ); + } + + return( etype ); +} /* enumerations from "../../libvips/include/vips/util.h" */ GType vips_token_get_type( void )