From 020073606ff31a61c48a21a98e505d3c88402b02 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 4 Nov 2011 17:55:06 +0000 Subject: [PATCH] add classes for all the math functions --- libvips/arithmetic/Makefile.am | 1 + libvips/arithmetic/arithmetic.c | 2 + libvips/arithmetic/math.c | 395 ++++++++++++------------------ libvips/arithmetic/v7math.c | 322 ++++++++++++++++++++++++ libvips/include/vips/Makefile.am | 1 + libvips/include/vips/arithmetic.h | 28 +++ libvips/include/vips/enumtypes.h | 3 + libvips/iofuncs/Makefile.am | 1 + libvips/iofuncs/enumtypes.c | 25 ++ 9 files changed, 539 insertions(+), 239 deletions(-) create mode 100644 libvips/arithmetic/v7math.c diff --git a/libvips/arithmetic/Makefile.am b/libvips/arithmetic/Makefile.am index 0a8778e8..2286c0b5 100644 --- a/libvips/arithmetic/Makefile.am +++ b/libvips/arithmetic/Makefile.am @@ -24,6 +24,7 @@ libarithmetic_la_SOURCES = \ min.c \ subtract.c \ math.c \ + v7math.c \ arithmetic.c \ arithmetic.h \ binary.c \ diff --git a/libvips/arithmetic/arithmetic.c b/libvips/arithmetic/arithmetic.c index 1a241744..d169c8df 100644 --- a/libvips/arithmetic/arithmetic.c +++ b/libvips/arithmetic/arithmetic.c @@ -507,6 +507,7 @@ vips_arithmetic_operation_init( void ) extern GType vips_avg_get_type( void ); extern GType vips_min_get_type( void ); extern GType vips_linear_get_type( void ); + extern GType vips_math_get_type( void ); vips_add_get_type(); vips_invert_get_type(); @@ -514,5 +515,6 @@ vips_arithmetic_operation_init( void ) vips_avg_get_type(); vips_min_get_type(); vips_linear_get_type(); + vips_math_get_type(); } diff --git a/libvips/arithmetic/math.c b/libvips/arithmetic/math.c index 94084415..86264f48 100644 --- a/libvips/arithmetic/math.c +++ b/libvips/arithmetic/math.c @@ -1,4 +1,4 @@ -/* math.c --- call various -lm functions (trig, log etc.) on imags +/* VipsMath --- call various -lm functions (trig, log etc.) on images * * Copyright: 1990, N. Dessipris, based on im_powtra() * Author: Nicos Dessipris @@ -21,23 +21,25 @@ * - use im__math() * 19/9/09 * - im_sintra() adapted to make math.c + * 4/11/11 + * - 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 + 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 Lesser General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License + 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 @@ -49,6 +51,10 @@ */ +/* +#define DEBUG + */ + #ifdef HAVE_CONFIG_H #include #endif /*HAVE_CONFIG_H*/ @@ -59,262 +65,173 @@ #include #include -#include -/* What we do for each band element. Non-complex only. - */ -#define FUN_LOOP( IN, OUT, FUN ) { \ - IN *p = (IN *) in; \ - OUT *q = (OUT *) out; \ - \ - for( x = 0; x < ne; x++ ) \ - q[x] = FUN( (double) p[x] ); \ -} +#include "arithmetic.h" +#include "unary.h" -/* Operate on a buffer of PELs +/** + * VipsMath: + * @in: input #VipsImage + * @out: output #VipsImage + * @operation: operation to perform + * + * Perform various functions in -lm, the maths library, on images. + * + * Angles are expressed in degrees. The output type is float unless the + * input is double, in which case the output is double. + * Non-complex images only. + * + * See also: #VipsAdd. */ -#define FUN_BUFFER( FUN ) \ -static void \ -FUN ## _buffer( PEL *in, PEL *out, int width, IMAGE *im ) \ -{ \ - const int ne = width * im->Bands; \ - \ - int x; \ - \ - /* Switch for all input types. \ - */ \ - switch( im->BandFmt ) { \ - case IM_BANDFMT_UCHAR: FUN_LOOP( unsigned char, float, FUN ); break; \ - case IM_BANDFMT_CHAR: FUN_LOOP( signed char, float, FUN ); break; \ - case IM_BANDFMT_USHORT: FUN_LOOP( unsigned short, float, FUN ); break; \ - case IM_BANDFMT_SHORT: FUN_LOOP( signed short, float, FUN ); break; \ - case IM_BANDFMT_UINT: FUN_LOOP( unsigned int, float, FUN ); break; \ - case IM_BANDFMT_INT: FUN_LOOP( signed int, float, FUN ); break; \ - case IM_BANDFMT_FLOAT: FUN_LOOP( float, float, FUN ); break; \ - case IM_BANDFMT_DOUBLE: FUN_LOOP( double, double, FUN ); break; \ - \ - default: \ - g_assert( 0 ); \ - } \ -} -/* Do a math (eg. sin(), acos(), log()) type-function. No complex, everything - * goes to float except double. - */ -int -im__math( const char *name, IMAGE *in, IMAGE *out, im_wrapone_fn gen ) +typedef struct _VipsMath { + VipsUnary parent_instance; + + VipsMathOperation operation; + +} VipsMath; + +typedef VipsUnaryClass VipsMathClass; + +G_DEFINE_TYPE( VipsMath, vips_math, VIPS_TYPE_UNARY ); + +static int +vips_math_build( VipsObject *object ) { - if( im_piocheck( in, out ) || - im_check_uncoded( name, in ) || - im_check_noncomplex( name, in ) ) + VipsUnary *unary = (VipsUnary *) object; + + if( unary->in && + vips_check_noncomplex( "VipsMath", unary->in ) ) return( -1 ); - if( im_cp_desc( out, in ) ) - return( -1 ); - if( vips_bandfmt_isint( in->BandFmt ) ) - out->BandFmt = IM_BANDFMT_FLOAT; - - if( im_wrapone( in, out, gen, in, NULL ) ) + if( VIPS_OBJECT_CLASS( vips_math_parent_class )->build( object ) ) return( -1 ); return( 0 ); } -/* Sin in degrees. +#define LOOP( IN, OUT, OP ) { \ + IN *p = (IN *) in[0]; \ + OUT *q = (OUT *) out; \ + \ + for( x = 0; x < sz; x++ ) \ + q[x] = OP( p[x] ); \ +} + +#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;\ + \ + default: \ + g_assert( 0 ); \ + } + +/* sin/cos/tan in degrees. */ #define DSIN( X ) (sin( IM_RAD( X ) )) - -FUN_BUFFER( DSIN ) - -/** - * im_sintra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call sin(3) (sine). Angles are - * expressed in degrees. The output type is float, unless the input is - * double, in which case the output is double. Non-complex images only. - * - * See also: im_asintra(), im_costra(), im_tantra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_sintra( IMAGE *in, IMAGE *out ) -{ - return( im__math( "im_sintra", in, out, (im_wrapone_fn) DSIN_buffer ) ); -} - -/* Asin in degrees. - */ -#define ADSIN( X ) (IM_DEG( asin( X ) )) - -FUN_BUFFER( ADSIN ) - -/** - * im_asintra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call asin(3) (arc, or inverse sine). - * Angles are - * expressed in degrees. The output type is float, unless the input is - * double, in which case the output is double. Non-complex images only. - * - * See also: im_asintra(), im_costra(), im_tantra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_asintra( IMAGE *in, IMAGE *out ) -{ - return( im__math( "im_asintra", in, out, - (im_wrapone_fn) ADSIN_buffer ) ); -} - -/* Cos in degrees. - */ #define DCOS( X ) (cos( IM_RAD( X ) )) - -FUN_BUFFER( DCOS ) - -/** - * im_costra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call cos(3) (cosine). Angles are - * expressed in degrees. The output type is float, unless the input is - * double, in which case the output is double. Non-complex images only. - * - * See also: im_acostra(), im_sintra(), im_tantra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_costra( IMAGE *in, IMAGE *out ) -{ - return( im__math( "im_costra", in, out, (im_wrapone_fn) DCOS_buffer ) ); -} - -/* Acos in degrees. - */ -#define ADCOS( X ) (IM_DEG( acos( X ) )) - -FUN_BUFFER( ADCOS ) - -/** - * im_acostra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call acos(3) (arc or inverse cosine). - * Angles are expressed in - * degrees. The output type is float, unless the input is double, in which - * case the output is double. Non-complex images only. - * - * See also: im_costra(), im_asintra(), im_atantra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_acostra( IMAGE *in, IMAGE *out ) -{ - return( im__math( "im_acostra", in, out, - (im_wrapone_fn) ADCOS_buffer ) ); -} - -/* Tan in degrees. - */ #define DTAN( X ) (tan( IM_RAD( X ) )) - -FUN_BUFFER( DTAN ) - -/** - * im_tantra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call tan(3) (tangent). Angles are - * expressed in degrees. The output type is float, unless the input is - * double, in which case the output is double. Non-complex images only. - * - * See also: im_atantra(), im_sintra(), im_tantra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_tantra( IMAGE *in, IMAGE *out ) -{ - return( im__math( "im_tantra", in, out, (im_wrapone_fn) DTAN_buffer ) ); -} - -/* Atan in degrees. - */ +#define ADSIN( X ) (IM_DEG( asin( X ) )) +#define ADCOS( X ) (IM_DEG( acos( X ) )) #define ADTAN( X ) (IM_DEG( atan( X ) )) -FUN_BUFFER( ADTAN ) - -/** - * im_atantra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call atan(3) (arc or inverse tangent). - * Angles are expressed in - * degrees. The output type is float, unless the input is double, in which - * case the output is double. Non-complex images only. - * - * See also: im_tantra(), im_asintra(), im_atantra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_atantra( IMAGE *in, IMAGE *out ) +static void +vips_math_buffer( VipsArithmetic *arithmetic, PEL *out, PEL **in, int width ) { - return( im__math( "im_atantra", in, out, - (im_wrapone_fn) ADTAN_buffer ) ); + VipsMath *math = (VipsMath *) arithmetic; + VipsImage *im = arithmetic->ready[0]; + const int sz = width * vips_image_get_bands( im ); + + int x; + + switch( math->operation ) { + case VIPS_MATH_OPERATION_SIN: SWITCH( DSIN ); break; + case VIPS_MATH_OPERATION_COS: SWITCH( DCOS ); break; + case VIPS_MATH_OPERATION_TAN: SWITCH( DTAN ); break; + case VIPS_MATH_OPERATION_ASIN: SWITCH( ADSIN ); break; + case VIPS_MATH_OPERATION_ACOS: SWITCH( ADCOS ); break; + case VIPS_MATH_OPERATION_ATAN: SWITCH( ADTAN ); break; + case VIPS_MATH_OPERATION_LOG10: SWITCH( log10 ); break; + case VIPS_MATH_OPERATION_LN: SWITCH( log ); break; + + default: + g_assert( 0 ); + } } -FUN_BUFFER( log10 ) - -/** - * im_log10tra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call log10(3) (base 10 logarithm). - * The output type is float, unless the input is - * double, in which case the output is double. Non-complex images only. - * - * See also: im_exp10tra(), im_logntra(), im_sintra(). - * - * Returns: 0 on success, -1 on error +/* Save a bit of typing. */ -int -im_log10tra( IMAGE *in, IMAGE *out ) +#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_math[10] = { +/* UC C US S UI I F X D DX */ + F, F, F, F, F, F, F, X, D, DX +}; + +static void +vips_math_class_init( VipsMathClass *class ) { - return( im__math( "im_log10tra", in, out, - (im_wrapone_fn) log10_buffer ) ); + 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 = "math"; + object_class->description = _( "perform a math function on an image" ); + object_class->build = vips_math_build; + + vips_arithmetic_set_format_table( aclass, vips_bandfmt_math ); + + aclass->process_line = vips_math_buffer; + + VIPS_ARG_ENUM( class, "operation", 200, + _( "Operation" ), + _( "operation to perform" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMath, operation ), + VIPS_TYPE_MATH_OPERATION, VIPS_MATH_OPERATION_SIN ); } -FUN_BUFFER( log ) - -/** - * im_logtra - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, call log(3) (natural logarithm). - * The output type is float, unless the input is - * double, in which case the output is double. Non-complex images only. - * - * See also: im_exp10tra(), im_logntra(), im_sintra(). - * - * Returns: 0 on success, -1 on error - */ -int -im_logtra( IMAGE *in, IMAGE *out ) +static void +vips_math_init( VipsMath *math ) { - return( im__math( "im_logtra", in, out, (im_wrapone_fn) log_buffer ) ); +} + +int +vips_math( VipsImage *in, VipsImage **out, VipsMathOperation operation, ... ) +{ + va_list ap; + int result; + + va_start( ap, operation ); + result = vips_call_split( "math", ap, in, out, operation ); + va_end( ap ); + + return( result ); } diff --git a/libvips/arithmetic/v7math.c b/libvips/arithmetic/v7math.c new file mode 100644 index 00000000..4b921a05 --- /dev/null +++ b/libvips/arithmetic/v7math.c @@ -0,0 +1,322 @@ +/* v7math.c --- call various -lm functions (trig, log etc.) on imags + * + * vips7 compat stuff + * + * Copyright: 1990, N. Dessipris, based on im_powtra() + * Author: Nicos Dessipris + * Written on: 02/05/1990 + * Modified on: + * 5/5/93 JC + * - adapted from im_lintra to work with partial images + * - incorrect implementation of complex logs removed + * 1/7/93 JC + * - adapted for partial v2 + * - ANSIfied + * 24/2/95 JC + * - im_logtra() adapted to make im_sintra() + * - adapted for im_wrapone() + * 26/1/96 JC + * - im_asintra() added + * 30/8/09 + * - gtkdoc + * - tiny cleanups + * - use im__math() + * 19/9/09 + * - im_sintra() adapted to make math.c + */ + +/* + + 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 +#include + +/* What we do for each band element. Non-complex only. + */ +#define FUN_LOOP( IN, OUT, FUN ) { \ + IN *p = (IN *) in; \ + OUT *q = (OUT *) out; \ + \ + for( x = 0; x < ne; x++ ) \ + q[x] = FUN( (double) p[x] ); \ +} + +/* Operate on a buffer of PELs + */ +#define FUN_BUFFER( FUN ) \ +static void \ +FUN ## _buffer( PEL *in, PEL *out, int width, IMAGE *im ) \ +{ \ + const int ne = width * im->Bands; \ + \ + int x; \ + \ + /* Switch for all input types. \ + */ \ + switch( im->BandFmt ) { \ + case IM_BANDFMT_UCHAR: FUN_LOOP( unsigned char, float, FUN ); break; \ + case IM_BANDFMT_CHAR: FUN_LOOP( signed char, float, FUN ); break; \ + case IM_BANDFMT_USHORT: FUN_LOOP( unsigned short, float, FUN ); break; \ + case IM_BANDFMT_SHORT: FUN_LOOP( signed short, float, FUN ); break; \ + case IM_BANDFMT_UINT: FUN_LOOP( unsigned int, float, FUN ); break; \ + case IM_BANDFMT_INT: FUN_LOOP( signed int, float, FUN ); break; \ + case IM_BANDFMT_FLOAT: FUN_LOOP( float, float, FUN ); break; \ + case IM_BANDFMT_DOUBLE: FUN_LOOP( double, double, FUN ); break; \ + \ + default: \ + g_assert( 0 ); \ + } \ +} + +/* Do a math (eg. sin(), acos(), log()) type-function. No complex, everything + * goes to float except double. + */ +int +im__math( const char *name, IMAGE *in, IMAGE *out, im_wrapone_fn gen ) +{ + if( im_piocheck( in, out ) || + im_check_uncoded( name, in ) || + im_check_noncomplex( name, in ) ) + return( -1 ); + + if( im_cp_desc( out, in ) ) + return( -1 ); + if( vips_bandfmt_isint( in->BandFmt ) ) + out->BandFmt = IM_BANDFMT_FLOAT; + + if( im_wrapone( in, out, gen, in, NULL ) ) + return( -1 ); + + return( 0 ); +} + +/* Sin in degrees. + */ +#define DSIN( X ) (sin( IM_RAD( X ) )) + +FUN_BUFFER( DSIN ) + +/** + * im_sintra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call sin(3) (sine). Angles are + * expressed in degrees. The output type is float, unless the input is + * double, in which case the output is double. Non-complex images only. + * + * See also: im_asintra(), im_costra(), im_tantra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_sintra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_sintra", in, out, (im_wrapone_fn) DSIN_buffer ) ); +} + +/* Asin in degrees. + */ +#define ADSIN( X ) (IM_DEG( asin( X ) )) + +FUN_BUFFER( ADSIN ) + +/** + * im_asintra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call asin(3) (arc, or inverse sine). + * Angles are + * expressed in degrees. The output type is float, unless the input is + * double, in which case the output is double. Non-complex images only. + * + * See also: im_asintra(), im_costra(), im_tantra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_asintra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_asintra", in, out, + (im_wrapone_fn) ADSIN_buffer ) ); +} + +/* Cos in degrees. + */ +#define DCOS( X ) (cos( IM_RAD( X ) )) + +FUN_BUFFER( DCOS ) + +/** + * im_costra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call cos(3) (cosine). Angles are + * expressed in degrees. The output type is float, unless the input is + * double, in which case the output is double. Non-complex images only. + * + * See also: im_acostra(), im_sintra(), im_tantra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_costra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_costra", in, out, (im_wrapone_fn) DCOS_buffer ) ); +} + +/* Acos in degrees. + */ +#define ADCOS( X ) (IM_DEG( acos( X ) )) + +FUN_BUFFER( ADCOS ) + +/** + * im_acostra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call acos(3) (arc or inverse cosine). + * Angles are expressed in + * degrees. The output type is float, unless the input is double, in which + * case the output is double. Non-complex images only. + * + * See also: im_costra(), im_asintra(), im_atantra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_acostra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_acostra", in, out, + (im_wrapone_fn) ADCOS_buffer ) ); +} + +/* Tan in degrees. + */ +#define DTAN( X ) (tan( IM_RAD( X ) )) + +FUN_BUFFER( DTAN ) + +/** + * im_tantra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call tan(3) (tangent). Angles are + * expressed in degrees. The output type is float, unless the input is + * double, in which case the output is double. Non-complex images only. + * + * See also: im_atantra(), im_sintra(), im_tantra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_tantra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_tantra", in, out, (im_wrapone_fn) DTAN_buffer ) ); +} + +/* Atan in degrees. + */ +#define ADTAN( X ) (IM_DEG( atan( X ) )) + +FUN_BUFFER( ADTAN ) + +/** + * im_atantra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call atan(3) (arc or inverse tangent). + * Angles are expressed in + * degrees. The output type is float, unless the input is double, in which + * case the output is double. Non-complex images only. + * + * See also: im_tantra(), im_asintra(), im_atantra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_atantra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_atantra", in, out, + (im_wrapone_fn) ADTAN_buffer ) ); +} + +FUN_BUFFER( log10 ) + +/** + * im_log10tra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call log10(3) (base 10 logarithm). + * The output type is float, unless the input is + * double, in which case the output is double. Non-complex images only. + * + * See also: im_exp10tra(), im_logntra(), im_sintra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_log10tra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_log10tra", in, out, + (im_wrapone_fn) log10_buffer ) ); +} + +FUN_BUFFER( log ) + +/** + * im_logtra + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, call log(3) (natural logarithm). + * The output type is float, unless the input is + * double, in which case the output is double. Non-complex images only. + * + * See also: im_exp10tra(), im_logntra(), im_sintra(). + * + * Returns: 0 on success, -1 on error + */ +int +im_logtra( IMAGE *in, IMAGE *out ) +{ + return( im__math( "im_logtra", in, out, (im_wrapone_fn) log_buffer ) ); +} diff --git a/libvips/include/vips/Makefile.am b/libvips/include/vips/Makefile.am index 95a15e1a..90fec84e 100644 --- a/libvips/include/vips/Makefile.am +++ b/libvips/include/vips/Makefile.am @@ -57,6 +57,7 @@ EXTRA_DIST = version.h.in internal.h enumtemplate # well vips_scan_headers = \ ${top_srcdir}/libvips/include/vips/memory.h \ + ${top_srcdir}/libvips/include/vips/arithmetic.h \ ${top_srcdir}/libvips/include/vips/conversion.h \ ${top_srcdir}/libvips/include/vips/util.h \ ${top_srcdir}/libvips/include/vips/buf.h \ diff --git a/libvips/include/vips/arithmetic.h b/libvips/include/vips/arithmetic.h index a2dbddf4..b72bd9a3 100644 --- a/libvips/include/vips/arithmetic.h +++ b/libvips/include/vips/arithmetic.h @@ -37,6 +37,31 @@ extern "C" { #endif /*__cplusplus*/ +/** + * VipsMathOperation: + * @VIPS_MATH_OPERATION_SIN: sin(), angles in degrees + * @VIPS_MATH_OPERATION_COS: cos(), angles in degrees + * @VIPS_MATH_OPERATION_TAN: tan(), angles in degrees + * @VIPS_MATH_OPERATION_ASIN: asin(), angles in degrees + * @VIPS_MATH_OPERATION_ACOS: acos(), angles in degrees + * @VIPS_MATH_OPERATION_ATAN: atan(), angles in degrees + * @VIPS_MATH_OPERATION_LOG10: log base 10 + * @VIPS_MATH_OPERATION_LN: log base e + * + * See also: vips_math(). + */ +typedef enum { + VIPS_MATH_OPERATION_SIN, + VIPS_MATH_OPERATION_COS, + VIPS_MATH_OPERATION_TAN, + VIPS_MATH_OPERATION_ASIN, + VIPS_MATH_OPERATION_ACOS, + VIPS_MATH_OPERATION_ATAN, + VIPS_MATH_OPERATION_LOG10, + VIPS_MATH_OPERATION_LN, + VIPS_MATH_OPERATION_LAST +} VipsMathOperation; + int vips_add( VipsImage *left, VipsImage *right, VipsImage **out, ... ) __attribute__((sentinel)); int vips_subtract( VipsImage *in1, VipsImage *in2, VipsImage **out, ... ) @@ -52,6 +77,9 @@ int vips_linear( VipsImage *in, VipsImage **out, __attribute__((sentinel)); int vips_linear1( VipsImage *in, VipsImage **out, double a, double b, ... ) __attribute__((sentinel)); +int vips_math( VipsImage *in, VipsImage **out, + VipsMathOperation operation, ... ) + __attribute__((sentinel)); diff --git a/libvips/include/vips/enumtypes.h b/libvips/include/vips/enumtypes.h index 73462d9c..6b6d8d85 100644 --- a/libvips/include/vips/enumtypes.h +++ b/libvips/include/vips/enumtypes.h @@ -6,6 +6,9 @@ G_BEGIN_DECLS +/* enumerations from "../../../libvips/include/vips/arithmetic.h" */ +GType vips_math_operation_get_type (void) G_GNUC_CONST; +#define VIPS_TYPE_MATH_OPERATION (vips_math_operation_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/iofuncs/Makefile.am b/libvips/iofuncs/Makefile.am index b28294c3..2a5f4b77 100644 --- a/libvips/iofuncs/Makefile.am +++ b/libvips/iofuncs/Makefile.am @@ -42,6 +42,7 @@ INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ vips_scan_headers = \ ${top_srcdir}/libvips/include/vips/memory.h \ ${top_srcdir}/libvips/include/vips/conversion.h \ + ${top_srcdir}/libvips/include/vips/arithmetic.h \ ${top_srcdir}/libvips/include/vips/util.h \ ${top_srcdir}/libvips/include/vips/buf.h \ ${top_srcdir}/libvips/include/vips/image.h \ diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index 4d699bf7..38cd15a7 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -83,6 +83,31 @@ vips_angle_get_type( void ) return( etype ); } +/* enumerations from "../../libvips/include/vips/arithmetic.h" */ +GType +vips_math_operation_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_MATH_OPERATION_SIN, "VIPS_MATH_OPERATION_SIN", "sin"}, + {VIPS_MATH_OPERATION_COS, "VIPS_MATH_OPERATION_COS", "cos"}, + {VIPS_MATH_OPERATION_TAN, "VIPS_MATH_OPERATION_TAN", "tan"}, + {VIPS_MATH_OPERATION_ASIN, "VIPS_MATH_OPERATION_ASIN", "asin"}, + {VIPS_MATH_OPERATION_ACOS, "VIPS_MATH_OPERATION_ACOS", "acos"}, + {VIPS_MATH_OPERATION_ATAN, "VIPS_MATH_OPERATION_ATAN", "atan"}, + {VIPS_MATH_OPERATION_LOG10, "VIPS_MATH_OPERATION_LOG10", "log10"}, + {VIPS_MATH_OPERATION_LN, "VIPS_MATH_OPERATION_LN", "ln"}, + {VIPS_MATH_OPERATION_LAST, "VIPS_MATH_OPERATION_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsMathOperation", values ); + } + + return( etype ); +} /* enumerations from "../../libvips/include/vips/util.h" */ GType vips_token_get_type( void )