From f705d28a66bbf5e2da17cce34599639f4d356b3a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 9 Sep 2009 09:54:02 +0000 Subject: [PATCH] im_rint(), im_sign() done --- libvips/arithmetic/im_abs.c | 3 +- libvips/arithmetic/im_ceil.c | 3 +- libvips/arithmetic/im_floor.c | 3 +- libvips/arithmetic/im_rint.c | 73 +++++++++++++++++------------ libvips/arithmetic/im_sign.c | 88 +++++++++++++++-------------------- 5 files changed, 86 insertions(+), 84 deletions(-) diff --git a/libvips/arithmetic/im_abs.c b/libvips/arithmetic/im_abs.c index bfd97989..a3710b4b 100644 --- a/libvips/arithmetic/im_abs.c +++ b/libvips/arithmetic/im_abs.c @@ -224,7 +224,8 @@ abs_gen( PEL *in, PEL *out, int width, IMAGE *im ) int im_abs( IMAGE *in, IMAGE *out ) { - if( im_check_uncoded( "im_abs", in ) ) + if( im_piocheck( in, out ) || + im_check_uncoded( "im_abs", in ) ) return( -1 ); /* Is this one of the unsigned types? Degenerate to im_copy() if it diff --git a/libvips/arithmetic/im_ceil.c b/libvips/arithmetic/im_ceil.c index 137b714d..6df9e70b 100644 --- a/libvips/arithmetic/im_ceil.c +++ b/libvips/arithmetic/im_ceil.c @@ -100,7 +100,8 @@ ceil_gen( PEL *in, PEL *out, int width, IMAGE *im ) int im_ceil( IMAGE *in, IMAGE *out ) { - if( im_check_uncoded( "im_ceil", in ) ) + 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 diff --git a/libvips/arithmetic/im_floor.c b/libvips/arithmetic/im_floor.c index 2e01d29c..a3819c7a 100644 --- a/libvips/arithmetic/im_floor.c +++ b/libvips/arithmetic/im_floor.c @@ -111,7 +111,8 @@ floor_gen( PEL *in, PEL *out, int width, IMAGE *im ) int im_floor( IMAGE *in, IMAGE *out ) { - if( im_check_uncoded( "im_floor", in ) ) + 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 diff --git a/libvips/arithmetic/im_rint.c b/libvips/arithmetic/im_rint.c index 13ffed1f..d0d897ab 100644 --- a/libvips/arithmetic/im_rint.c +++ b/libvips/arithmetic/im_rint.c @@ -1,14 +1,9 @@ -/* @(#) rint() an image ... no promotion, so output type == input type - * @(#) - * @(#) int - * @(#) im_rint( in, out ) - * @(#) IMAGE *in, *out; - * @(#) - * @(#) Returns 0 on success and -1 on error - * @(#) +/* im_rint.c * * 20/6/02 JC * - adapted from im_floor() + * 9/9/09 + * - updated from new im_floor() */ /* @@ -53,45 +48,63 @@ #include #endif /*WITH_DMALLOC*/ -#define rint_loop(TYPE)\ - {\ - TYPE *p = (TYPE *) in;\ - TYPE *q = (TYPE *) out;\ - \ - for( x = 0; x < sz; x++ )\ - q[x] = IM_RINT( p[x] );\ - } +#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. +/* 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; - int sz = width * im->Bands; switch( im->BandFmt ) { - case IM_BANDFMT_FLOAT: rint_loop(float); break; - case IM_BANDFMT_DOUBLE: rint_loop(double); break; - case IM_BANDFMT_COMPLEX: sz *= 2; rint_loop(float); break; - case IM_BANDFMT_DPCOMPLEX: sz *= 2; rint_loop(double); break; + case IM_BANDFMT_COMPLEX: + case IM_BANDFMT_FLOAT: + RINT( float ); + break; + + case IM_BANDFMT_DOUBLE: + case IM_BANDFMT_DPCOMPLEX: + RINT( double ); + break; default: - assert( 0 ); + g_assert( 0 ); } } -/* rint of image. +/** + * 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 ) -{ - /* Check args. - */ - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_rint", "%s", _( "not uncoded" ) ); +{ + 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. diff --git a/libvips/arithmetic/im_sign.c b/libvips/arithmetic/im_sign.c index 783016d9..305f792c 100644 --- a/libvips/arithmetic/im_sign.c +++ b/libvips/arithmetic/im_sign.c @@ -1,13 +1,9 @@ -/* @(#) Find the unit vector in the direction of the pixel. - * @(#) - * @(#) int im_sign(in, out) - * @(#) IMAGE *in, *out; - * @(#) - * @(#) Returns 0 on success and -1 on error - * @(#) +/* im_sign.c * * 9/7/02 JC * - from im_cmulnorm + * 9/9/09 + * - gtkdoc, tidies */ /* @@ -52,8 +48,7 @@ #include #endif /*WITH_DMALLOC*/ -#define sign_complex( IN, OUT ) \ -{ \ +#define CSIGN( IN, OUT ) { \ IN *p = (IN *) in; \ OUT *q = (OUT *) out; \ int x; \ @@ -78,8 +73,7 @@ } \ } -#define sign( IN, OUT ) \ -{ \ +#define SIGN( IN, OUT ) { \ IN *p = (IN *) in; \ OUT *q = (OUT *) out; \ int x; \ @@ -99,63 +93,55 @@ /* sign buffer processor. */ static void -buffer_sign( void *in, void *out, int w, IMAGE *im ) +sign_gen( void *in, void *out, int w, IMAGE *im ) { int n = w * im->Bands; switch( im->BandFmt ) { - case IM_BANDFMT_UCHAR: - sign( unsigned char, signed char ); - break; - case IM_BANDFMT_CHAR: - sign( signed char, signed char ); - break; - case IM_BANDFMT_USHORT: - sign( unsigned short, signed char ); - break; - case IM_BANDFMT_SHORT: - sign( signed short, signed char ); - break; - case IM_BANDFMT_UINT: - sign( unsigned int, signed char ); - break; - case IM_BANDFMT_INT: - sign( signed int, signed char ); - break; - case IM_BANDFMT_FLOAT: - sign( float, signed char ); - break; - case IM_BANDFMT_DOUBLE: - sign( double, signed char ); - break; - case IM_BANDFMT_COMPLEX: - sign_complex( float, float ); - break; - case IM_BANDFMT_DPCOMPLEX: - sign_complex( double, double ); - break; + case IM_BANDFMT_UCHAR: SIGN( unsigned char, signed char ); break; + case IM_BANDFMT_CHAR: SIGN( signed char, signed char ); break; + case IM_BANDFMT_USHORT: SIGN( unsigned short, signed char ); break; + case IM_BANDFMT_SHORT: SIGN( signed short, signed char ); break; + case IM_BANDFMT_UINT: SIGN( unsigned int, signed char ); break; + case IM_BANDFMT_INT: SIGN( signed int, signed char ); break; + case IM_BANDFMT_FLOAT: SIGN( float, signed char ); break; + case IM_BANDFMT_DOUBLE: SIGN( double, signed char ); break; + case IM_BANDFMT_COMPLEX: CSIGN( float, float ); break; + case IM_BANDFMT_DPCOMPLEX: CSIGN( double, double ); break; + default: - assert( 0 ); + g_assert( 0 ); } } +/** + * im_sign: + * @in: input image + * @out: output image + * + * Finds the unit vector in the direction of the pixel value. For non-complex + * images, it returns a signed char image with values -1, 0, and 1 for negative, + * zero and positive pixels. For complex images, it returns a + * complex normalised to length 1. + * + * See also: im_abs(), im_cmulnorm(), im_c2amph(). + * + * Returns: 0 on success, -1 on error + */ int im_sign( IMAGE *in, IMAGE *out ) { - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_sign", "%s", _( "not uncoded" ) ); - return( -1 ); - } - if( im_cp_desc( out, in ) ) + if( im_piocheck( in, out ) || + im_check_uncoded( "im_sign", in ) || + im_cp_desc( out, in ) ) return( -1 ); + if( !im_iscomplex( in ) ) { out->Bbits = IM_BBITS_BYTE; out->BandFmt = IM_BANDFMT_CHAR; } - /* Do the processing. - */ - if( im_wrapone( in, out, (im_wrapone_fn) buffer_sign, in, NULL ) ) + if( im_wrapone( in, out, (im_wrapone_fn) sign_gen, in, NULL ) ) return( -1 ); return( 0 );