From 4ee4fe13a96bfd1d16e23cb20d887ef60d159128 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 19 Sep 2009 11:13:28 +0000 Subject: [PATCH] common up round operations --- libvips/arithmetic/Makefile.am | 4 +- libvips/arithmetic/im_ceil.c | 125 ----------------------- libvips/arithmetic/im_costra.c | 177 -------------------------------- libvips/arithmetic/im_floor.c | 136 ------------------------- libvips/arithmetic/im_rint.c | 127 ----------------------- libvips/arithmetic/round.c | 180 +++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 568 deletions(-) delete mode 100644 libvips/arithmetic/im_ceil.c delete mode 100644 libvips/arithmetic/im_costra.c delete mode 100644 libvips/arithmetic/im_floor.c delete mode 100644 libvips/arithmetic/im_rint.c create mode 100644 libvips/arithmetic/round.c diff --git a/libvips/arithmetic/Makefile.am b/libvips/arithmetic/Makefile.am index 9a863dff..5040fe52 100644 --- a/libvips/arithmetic/Makefile.am +++ b/libvips/arithmetic/Makefile.am @@ -10,8 +10,6 @@ libarithmetic_la_SOURCES = \ im_cross_phase.c \ im_deviate.c \ im_divide.c \ - im_ceil.c \ - im_floor.c \ im_expntra.c \ im_invert.c \ im_linreg.c \ @@ -24,7 +22,7 @@ libarithmetic_la_SOURCES = \ im_multiply.c \ im_powtra.c \ im_remainder.c \ - im_rint.c \ + round.c \ im_sign.c \ math.c \ im_stats.c \ diff --git a/libvips/arithmetic/im_ceil.c b/libvips/arithmetic/im_ceil.c deleted file mode 100644 index 6df9e70b..00000000 --- a/libvips/arithmetic/im_ceil.c +++ /dev/null @@ -1,125 +0,0 @@ -/* im_ceil.c - * - * 20/6/02 JC - * - adapted from im_abs() - * 29/8/09 - * - gtkdoc - * - tiny 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., 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 - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -#define LOOP( TYPE ) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - \ - for( x = 0; x < sz; x++ ) \ - q[x] = ceil( p[x] ); \ -} - -/* Ceil a buffer of PELs. - */ -static void -ceil_gen( PEL *in, PEL *out, int width, IMAGE *im ) -{ - /* Complex just doubles the size. - */ - const int sz = width * im->Bands * (im_iscomplex( im ) ? 2 : 1); - - int x; - - switch( im->BandFmt ) { - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_FLOAT: - LOOP( float ); - break; - - case IM_BANDFMT_DOUBLE: - case IM_BANDFMT_DPCOMPLEX: - LOOP( double ); - break; - - default: - g_assert( 0 ); - } -} - -/** - * im_ceil: - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, find the smallest integral value not less than. - * Copy for integer types, call ceil(3) for float and - * complex types. - * Output type == input type. - * - * See also: im_floor(), im_rint(), im_clip2fmt() - * - * Returns: 0 on success, -1 on error - */ -int -im_ceil( IMAGE *in, IMAGE *out ) -{ - if( im_piocheck( in, out ) || - im_check_uncoded( "im_ceil", in ) ) - return( -1 ); - - /* Is this one of the int types? Degenerate to im_copy() if it - * is. - */ - if( im_isint( in ) ) - return( im_copy( in, out ) ); - - /* Output type == input type. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - - /* Generate! - */ - if( im_wrapone( in, out, - (im_wrapone_fn) ceil_gen, in, NULL ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/arithmetic/im_costra.c b/libvips/arithmetic/im_costra.c deleted file mode 100644 index 8592dfbf..00000000 --- a/libvips/arithmetic/im_costra.c +++ /dev/null @@ -1,177 +0,0 @@ -/* im_costra - * - * 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_costra() - * - adapted for im_wrapone() - * 26/1/96 JC - * - im_acostra() added - * 30/8/09 - * - gtkdoc - * - tiny cleanups - * - make im__math(), share with other math-style functions - */ - -/* - - 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 - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Define what we do for each band element type. Non-complex input, any - * output. - */ -#define COS( IN, OUT ) { \ - IN *p = (IN *) in; \ - OUT *q = (OUT *) out; \ - \ - for( x = 0; x < sz; x++ ) \ - q[x] = cos( IM_RAD( (double) p[x] ) ); \ -} - -/* cos a buffer of PELs. - */ -static void -costra_gen( PEL *in, PEL *out, int width, IMAGE *im ) -{ - const int sz = width * im->Bands; - - int x; - - /* Switch for all input types. - */ - switch( im->BandFmt ) { - case IM_BANDFMT_UCHAR: COS( unsigned char, float ); break; - case IM_BANDFMT_CHAR: COS( signed char, float ); break; - case IM_BANDFMT_USHORT: COS( unsigned short, float ); break; - case IM_BANDFMT_SHORT: COS( signed short, float ); break; - case IM_BANDFMT_UINT: COS( unsigned int, float ); break; - case IM_BANDFMT_INT: COS( signed int, float ); break; - case IM_BANDFMT_FLOAT: COS( float, float ); break; - case IM_BANDFMT_DOUBLE: COS( double, double ); break; - - default: - g_assert( 0 ); - } -} - -/** - * 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) costra_gen ) ); -} - -/* And acos(). - */ -#define ACOS( IN, OUT ) { \ - IN *p = (IN *) in; \ - OUT *q = (OUT *) out; \ - \ - for( x = 0; x < sz; x++ ) \ - q[x] = IM_DEG( acos( (double) p[x] ) ); \ -} - -/* acos a buffer of PELs. - */ -static void -acostra_gen( PEL *in, PEL *out, int width, IMAGE *im ) -{ - const int sz = width * im->Bands; - - int x; - - /* Switch for all input types. - */ - switch( im->BandFmt ) { - case IM_BANDFMT_UCHAR: ACOS( unsigned char, float ); break; - case IM_BANDFMT_CHAR: ACOS( signed char, float ); break; - case IM_BANDFMT_USHORT: ACOS( unsigned short, float ); break; - case IM_BANDFMT_SHORT: ACOS( signed short, float ); break; - case IM_BANDFMT_UINT: ACOS( unsigned int, float ); break; - case IM_BANDFMT_INT: ACOS( signed int, float ); break; - case IM_BANDFMT_FLOAT: ACOS( float, float ); break; - case IM_BANDFMT_DOUBLE: ACOS( double, double ); break; - - default: - g_assert( 0 ); - } -} - - -/** - * 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) acostra_gen ) ); -} diff --git a/libvips/arithmetic/im_floor.c b/libvips/arithmetic/im_floor.c deleted file mode 100644 index a3819c7a..00000000 --- a/libvips/arithmetic/im_floor.c +++ /dev/null @@ -1,136 +0,0 @@ -/* im_floor.c - * - * 20/6/02 JC - * - adapted from im_abs() - * 8/12/06 - * - add liboil support - * 2/9/09 - * - gtkdoc - * - tiny 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., 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 - -#ifdef HAVE_LIBOIL -#include -#endif /*HAVE_LIBOIL*/ - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -#define FLOOR( TYPE ) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - \ - for( x = 0; x < sz; x++ ) \ - q[x] = floor( p[x] ); \ -} - -/* Ceil a buffer of PELs. - */ -static void -floor_gen( PEL *in, PEL *out, int width, IMAGE *im ) -{ - /* Complex just doubles the size. - */ - const int sz = width * im->Bands * (im_iscomplex( im ) ? 2 : 1); - - int x; - - switch( im->BandFmt ) { - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_FLOAT: -#ifdef HAVE_LIBOIL - oil_floor_f32( (float *) out, (float *) in, sz ); -#else /*!HAVE_LIBOIL*/ - FLOOR( float ); -#endif /*HAVE_LIBOIL*/ - break; - - case IM_BANDFMT_DOUBLE: - case IM_BANDFMT_DPCOMPLEX: - FLOOR( double ); - break; - - default: - g_assert( 0 ); - } -} - -/** - * im_floor: - * @in: input #IMAGE - * @out: output #IMAGE - * - * For each pixel, find the largest integral value not less than. - * Copy for integer types, call floor() for float and - * complex types. - * Output type == input type. - * - * See also: im_ceil(), im_rint(), im_clip2fmt() - * - * Returns: 0 on success, -1 on error - */ -int -im_floor( IMAGE *in, IMAGE *out ) -{ - if( im_piocheck( in, out ) || - im_check_uncoded( "im_floor", in ) ) - return( -1 ); - - /* Is this one of the int types? Degenerate to im_copy() if it - * is. - */ - if( im_isint( in ) ) - return( im_copy( in, out ) ); - - /* Output type == input type. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - - /* Generate! - */ - if( im_wrapone( in, out, - (im_wrapone_fn) floor_gen, in, NULL ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/arithmetic/im_rint.c b/libvips/arithmetic/im_rint.c deleted file mode 100644 index d0d897ab..00000000 --- a/libvips/arithmetic/im_rint.c +++ /dev/null @@ -1,127 +0,0 @@ -/* im_rint.c - * - * 20/6/02 JC - * - adapted from im_floor() - * 9/9/09 - * - updated from new im_floor() - */ - -/* - - 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 - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -#define RINT( TYPE ) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - \ - for( x = 0; x < sz; x++ ) \ - q[x] = IM_RINT( p[x] );\ -} - -/* RINT a buffer of PELs. - */ -static void -rint_gen( PEL *in, PEL *out, int width, IMAGE *im ) -{ - /* Complex just doubles the size. - */ - const int sz = width * im->Bands * (im_iscomplex( im ) ? 2 : 1); - - int x; - - switch( im->BandFmt ) { - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_FLOAT: - RINT( float ); - break; - - case IM_BANDFMT_DOUBLE: - case IM_BANDFMT_DPCOMPLEX: - RINT( double ); - break; - - default: - g_assert( 0 ); - } -} - -/** - * im_rint: - * @in: input #IMAGE - * @out: output #IMAGE - * - * Finds the nearest integral value. Copy for integer types, - * call IM_RINT() for float and complex types. Output type == input type. - * - * IM_RINT() is a pseudo-round-to-nearest. It is much faster than - * rint(3), but does not give the same result for - * negative integral values. - * - * See also: im_ceil(), im_floor(), im_clip2fmt() - * - * Returns: 0 on success, -1 on error - */ -int -im_rint( IMAGE *in, IMAGE *out ) -{ - if( im_piocheck( in, out ) || - im_check_uncoded( "im_rint", in ) ) - return( -1 ); - - /* Is this one of the int types? Degenerate to im_copy() if it - * is. - */ - if( im_isint( in ) ) - return( im_copy( in, out ) ); - - /* Output type == input type. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - - /* Generate! - */ - if( im_wrapone( in, out, - (im_wrapone_fn) rint_gen, in, NULL ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c new file mode 100644 index 00000000..ed2ca4e9 --- /dev/null +++ b/libvips/arithmetic/round.c @@ -0,0 +1,180 @@ +/* round.c --- various rounding operations + * + * 20/6/02 JC + * - adapted from im_abs() + * 29/8/09 + * - gtkdoc + * - tiny cleanups + * 19/9/09 + * - im_ceil.c adapted to make round.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 + +#ifdef WITH_DMALLOC +#include +#endif /*WITH_DMALLOC*/ + +#define ROUND_LOOP( TYPE, FUN ) { \ + TYPE *p = (TYPE *) in; \ + TYPE *q = (TYPE *) out; \ + \ + for( x = 0; x < ne; x++ ) \ + q[x] = FUN( p[x] ); \ +} + +#define ROUND_BUFFER( FUN ) \ +static void \ +FUN ## _buffer( PEL *in, PEL *out, int width, IMAGE *im ) \ +{ \ + /* Complex just doubles the size. \ + */ \ + const int ne = width * im->Bands * (im_iscomplex( im ) ? 2 : 1); \ + \ + int x; \ + \ + switch( im->BandFmt ) { \ + case IM_BANDFMT_COMPLEX: \ + case IM_BANDFMT_FLOAT: \ + ROUND_LOOP( float, FUN ); \ + break; \ + \ + case IM_BANDFMT_DOUBLE: \ + case IM_BANDFMT_DPCOMPLEX: \ + ROUND_LOOP( double, FUN ); \ + break; \ + \ + default: \ + g_assert( 0 ); \ + } \ +} + +static int +im__round( const char *name, IMAGE *in, IMAGE *out, im_wrapone_fn gen ) +{ + if( im_piocheck( in, out ) || + im_check_uncoded( name, in ) ) + return( -1 ); + + /* Is this one of the int types? Degenerate to im_copy() if it + * is. + */ + if( im_isint( in ) ) + return( im_copy( in, out ) ); + + /* Output type == input type. + */ + if( im_cp_desc( out, in ) ) + return( -1 ); + + /* Generate! + */ + if( im_wrapone( in, out, (im_wrapone_fn) gen, in, NULL ) ) + return( -1 ); + + return( 0 ); +} + +ROUND_BUFFER( ceil ) + +/** + * im_ceil: + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, find the smallest integral value not less than. + * Copy for integer types, call ceil(3) for float and + * complex types. + * Output type == input type. + * + * See also: im_floor(), im_rint(), im_clip2fmt() + * + * Returns: 0 on success, -1 on error + */ +int +im_ceil( IMAGE *in, IMAGE *out ) +{ + return( im__round( "im_ceil", in, out, (im_wrapone_fn) ceil_buffer ) ); +} + +ROUND_BUFFER( floor ) + +/** + * im_floor: + * @in: input #IMAGE + * @out: output #IMAGE + * + * For each pixel, find the largest integral value not less than. + * Copy for integer types, call floor() for float and + * complex types. + * Output type == input type. + * + * See also: im_ceil(), im_rint(), im_clip2fmt() + * + * Returns: 0 on success, -1 on error + */ +int +im_floor( IMAGE *in, IMAGE *out ) +{ + return( im__round( "im_floor", in, out, + (im_wrapone_fn) floor_buffer ) ); +} + +ROUND_BUFFER( IM_RINT ) + +/** + * im_rint: + * @in: input #IMAGE + * @out: output #IMAGE + * + * Finds the nearest integral value. Copy for integer types, + * call IM_RINT() for float and complex types. Output type == input type. + * + * IM_RINT() is a pseudo-round-to-nearest. It is much faster than + * rint(3), but does not give the same result for + * negative integral values. + * + * See also: im_ceil(), im_floor(), im_clip2fmt() + * + * Returns: 0 on success, -1 on error + */ +int +im_rint( IMAGE *in, IMAGE *out ) +{ + return( im__round( "im_rint", in, out, (im_wrapone_fn) IM_RINT_buffer ) ); +}