diff --git a/ChangeLog b/ChangeLog index 20bb91ef..053c9f1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ (thank you Ole) - im_buildlut() could segv for non-zero based tables (thanks Jack) - VIPS_BUF_STATIC() does not take length arg +- add and use im_check_uncoded() and friends 25/3/09 started 7.18.0 - revised version numbers diff --git a/TODO b/TODO index b170e70f..a153994c 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,28 @@ +- make some check functions like + + int + im_check_isuncoded( IMAGE *im ) + { + if( im->Coding != IM_CODING_NONE ) { + im_error( "im_check_isuncoded", "%s", + _( "image should be uncoded" ) ); + return( -1 ) + } + + return( 0 ); + } + + then operations can start with + + if( im_check_isuncoded( in ) || + im_check_isuchar( in ) || + im_check_ismono( in ) ) + return( -1 ); + + + + reached im_expntra() in arith + - 1-bit PNG readis broken? > The bug is that 1bit depth PNG addresses are incorrectly interpreted. At diff --git a/include/vips/proto.h b/include/vips/proto.h index 5e49b9e7..6648fc48 100644 --- a/include/vips/proto.h +++ b/include/vips/proto.h @@ -138,6 +138,15 @@ int im_amiMSBfirst( void ); int im_ispoweroftwo( int ); +int im_check_uncoded( const char *domain, IMAGE *im ); +int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_noncomplex( const char *domain, IMAGE *im ); +int im_check_complex( const char *domain, IMAGE *im ); +int im_check_size( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_bands( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_format( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_vector( const char *domain, int n, IMAGE *im ); + int im_existsf( const char *name, ... ) __attribute__((format(printf, 1, 2))); int im_isvips( const char * ); diff --git a/libsrc/arithmetic/im_abs.c b/libsrc/arithmetic/im_abs.c index fa9cda5b..f3aac245 100644 --- a/libsrc/arithmetic/im_abs.c +++ b/libsrc/arithmetic/im_abs.c @@ -26,6 +26,8 @@ * - tiny speed up * 8/12/06 * - add liboil support + * 29/7/09 + * - small cleanups and speedups */ /* @@ -77,73 +79,77 @@ /* Integer abs operation: just test and negate. */ -#define intabs(TYPE) \ - { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - int x; \ +#define intabs( TYPE ) { \ + TYPE *p = (TYPE *) in; \ + TYPE *q = (TYPE *) out; \ + int x; \ + \ + for( x = 0; x < sz; x++ ) { \ + TYPE v = p[x]; \ \ - for( x = 0; x < sz; x++ ) { \ - TYPE v = p[x]; \ - \ - if( v < 0 ) \ - q[x] = 0 - v; \ - else \ - q[x] = v; \ - } \ - } + if( v < 0 ) \ + q[x] = 0 - v; \ + else \ + q[x] = v; \ + } \ +} /* Float abs operation: call fabs(). */ -#define floatabs(TYPE)\ - {\ - TYPE *p = (TYPE *) in;\ - TYPE *q = (TYPE *) out;\ - int x; \ - \ - for( x = 0; x < sz; x++ )\ - q[x] = fabs( p[x] );\ - } +#define floatabs( TYPE ) { \ + TYPE *p = (TYPE *) in; \ + TYPE *q = (TYPE *) out; \ + int x; \ + \ + for( x = 0; x < sz; x++ ) \ + q[x] = fabs( p[x] ); \ +} /* Complex abs operation: calculate modulus. */ #ifdef HAVE_HYPOT -#define complexabs(TYPE) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - int i; \ - \ - for( i = 0; i < sz; i++ ) { \ - q[i] = hypot( p[0], p[1] ); \ - p += 2; \ - } \ - } +#define complexabs( TYPE ) { \ + TYPE *p = (TYPE *) in; \ + TYPE *q = (TYPE *) out; \ + int i; \ + \ + for( i = 0; i < sz; i++ ) { \ + q[i] = hypot( p[0], p[1] ); \ + p += 2; \ + } \ +} #else /*HAVE_HYPOT*/ -#define complexabs(TYPE) { \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ - TYPE *q_stop = q + sz; \ - \ - while( q < q_stop ){ \ - double rp = *p++; \ - double ip = *p++; \ - double abs_rp= fabs( rp ); \ - double abs_ip= fabs( ip ); \ - \ - if( abs_rp > abs_ip ){ \ - double temp= ip / rp; \ - *q++= abs_rp * sqrt( 1.0 + temp * temp ); \ - } \ - else { \ - double temp= rp / ip; \ - *q++= abs_ip * sqrt( 1.0 + temp * temp ); \ - } \ - } \ - } +#define complexabs( TYPE ) { \ + TYPE *p = (TYPE *) in; \ + TYPE *q = (TYPE *) out; \ + int i; \ + \ + for( i = 0; i < sz; i++ ) { \ + double rp = p[0]; \ + double ip = p[1]; \ + double abs_rp = fabs( rp ); \ + double abs_ip = fabs( ip ); \ + double result; + \ + if( abs_rp > abs_ip ) { \ + double temp = ip / rp; \ + \ + result = abs_rp * sqrt( 1.0 + temp * temp ); \ + } \ + else { \ + double temp = rp / ip; \ + \ + result = abs_ip * sqrt( 1.0 + temp * temp ); \ + } \ + \ + p += 2; \ + q[i] = result; \ + } \ +} #endif /*HAVE_HYPOT*/ @@ -154,8 +160,6 @@ abs_gen( PEL *in, PEL *out, int width, IMAGE *im ) { int sz = width * im->Bands; - /* Abs all input types. - */ switch( im->BandFmt ) { case IM_BANDFMT_CHAR: #ifdef HAVE_LIBOIL @@ -214,13 +218,9 @@ abs_gen( PEL *in, PEL *out, int width, IMAGE *im ) */ int im_abs( IMAGE *in, IMAGE *out ) -{ - /* Check args. - */ - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_abs", "%s", _( "not uncoded" ) ); +{ + if( im_check_uncoded( "im_abs", in ) ) return( -1 ); - } /* Is this one of the unsigned types? Degenerate to im_copy() if it * is. @@ -233,16 +233,8 @@ im_abs( IMAGE *in, IMAGE *out ) */ if( im_cp_desc( out, in ) ) return( -1 ); - switch( in->BandFmt ) { - case IM_BANDFMT_CHAR: - case IM_BANDFMT_SHORT: - case IM_BANDFMT_INT: - case IM_BANDFMT_FLOAT: - case IM_BANDFMT_DOUBLE: - /* No action. - */ - break; + switch( in->BandFmt ) { case IM_BANDFMT_COMPLEX: out->Bbits = IM_BBITS_FLOAT; out->BandFmt = IM_BANDFMT_FLOAT; @@ -254,14 +246,10 @@ im_abs( IMAGE *in, IMAGE *out ) break; default: - im_error( "im_abs", "%s", _( "unknown input type" ) ); - return( -1 ); + break; } - /* Generate! - */ - if( im_wrapone( in, out, - (im_wrapone_fn) abs_gen, in, NULL ) ) + if( im_wrapone( in, out, (im_wrapone_fn) abs_gen, in, NULL ) ) return( -1 ); return( 0 ); diff --git a/libsrc/arithmetic/im_add.c b/libsrc/arithmetic/im_add.c index 1fc73b3c..2273d24e 100644 --- a/libsrc/arithmetic/im_add.c +++ b/libsrc/arithmetic/im_add.c @@ -241,20 +241,14 @@ im__cast_and_call( IMAGE *in1, IMAGE *in2, IMAGE *out, int im_add( IMAGE *in1, IMAGE *in2, IMAGE *out ) -{ - /* Basic checks. - */ - if( im_piocheck( in1, out ) || im_pincheck( in2 ) ) +{ + if( im_piocheck( in1, out ) || + im_pincheck( in2 ) || + im_check_bands_1orn( "im_add", in1, in2 ) || + im_check_uncoded( "im_add", in1 ) || + im_check_uncoded( "im_add", in2 ) ) return( -1 ); - if( in1->Bands != in2->Bands && - (in1->Bands != 1 && in2->Bands != 1) ) { - im_error( "im_add", "%s", _( "not same number of bands" ) ); - return( -1 ); - } - if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) { - im_error( "im_add", "%s", _( "not uncoded" ) ); - return( -1 ); - } + if( im_cp_descv( out, in1, in2, NULL ) ) return( -1 ); diff --git a/libsrc/arithmetic/im_avg.c b/libsrc/arithmetic/im_avg.c index 21aac595..9ba3f8f8 100644 --- a/libsrc/arithmetic/im_avg.c +++ b/libsrc/arithmetic/im_avg.c @@ -181,16 +181,10 @@ im_avg( IMAGE *in, double *out ) /* Check our args. */ - if( im_pincheck( in ) ) + if( im_pincheck( in ) || + im_check_noncomplex( "im_avg", in ) || + im_check_uncoded( "im_avg", in ) ) return( -1 ); - if( im_iscomplex( in ) ) { - im_error( "im_avg", "%s", _( "bad input type" ) ); - return( -1 ); - } - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_avg", "%s", _( "not uncoded" ) ); - return( -1 ); - } /* Loop over input, summing pixels. */ diff --git a/libsrc/arithmetic/im_bandmean.c b/libsrc/arithmetic/im_bandmean.c index dd602afb..c1c2f1e8 100644 --- a/libsrc/arithmetic/im_bandmean.c +++ b/libsrc/arithmetic/im_bandmean.c @@ -123,8 +123,8 @@ bandmean_buffer( PEL *p, PEL *q, int n, IMAGE *in ) case IM_BANDFMT_UINT: ILOOP( unsigned int, unsigned int ); break; case IM_BANDFMT_FLOAT: FLOOP( float ); break; case IM_BANDFMT_DOUBLE: FLOOP( double ); break; - case IM_BANDFMT_COMPLEX: CLOOP( float ); break; - case IM_BANDFMT_DPCOMPLEX: CLOOP( double ); break; + case IM_BANDFMT_COMPLEX:CLOOP( float ); break; + case IM_BANDFMT_DPCOMPLEX:CLOOP( double ); break; default: assert( 0 ); @@ -134,24 +134,16 @@ bandmean_buffer( PEL *p, PEL *q, int n, IMAGE *in ) int im_bandmean( IMAGE *in, IMAGE *out ) { - /* Check input params - */ if( in->Bands == 1 ) return( im_copy( in, out ) ); - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_bandmean", "%s", _( "uncoded multiband only" ) ); + if( im_check_uncoded( "im_bandmean", in ) ) return( -1 ); - } - /* Prepare output image. - */ if( im_cp_desc( out, in ) ) return( -1 ); out->Bands = 1; out->Type = IM_TYPE_B_W; - /* And process! - */ if( im_wrapone( in, out, (im_wrapone_fn) bandmean_buffer, in, NULL ) ) return( -1 ); diff --git a/libsrc/arithmetic/im_ceil.c b/libsrc/arithmetic/im_ceil.c index eb3eb290..96f45707 100644 --- a/libsrc/arithmetic/im_ceil.c +++ b/libsrc/arithmetic/im_ceil.c @@ -53,14 +53,13 @@ #include #endif /*WITH_DMALLOC*/ -#define ceil_loop(TYPE)\ - {\ - TYPE *p = (TYPE *) in;\ - TYPE *q = (TYPE *) out;\ - \ - for( x = 0; x < sz; x++ )\ - q[x] = ceil( p[x] );\ - } +#define ceil_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. */ @@ -85,13 +84,9 @@ ceil_gen( PEL *in, PEL *out, int width, IMAGE *im ) */ int im_ceil( IMAGE *in, IMAGE *out ) -{ - /* Check args. - */ - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_ceil", "%s", _( "not uncoded" ) ); +{ + if( im_check_uncoded( "im_ceil", in ) ) return( -1 ); - } /* Is this one of the int types? Degenerate to im_copy() if it * is. @@ -106,8 +101,7 @@ im_ceil( IMAGE *in, IMAGE *out ) /* Generate! */ - if( im_wrapone( in, out, - (im_wrapone_fn) ceil_gen, in, NULL ) ) + if( im_wrapone( in, out, (im_wrapone_fn) ceil_gen, in, NULL ) ) return( -1 ); return( 0 ); diff --git a/libsrc/arithmetic/im_costra.c b/libsrc/arithmetic/im_costra.c index abe022c4..52e2f344 100644 --- a/libsrc/arithmetic/im_costra.c +++ b/libsrc/arithmetic/im_costra.c @@ -111,16 +111,10 @@ im_costra( IMAGE *in, IMAGE *out ) { /* Check args. */ - if( im_piocheck( in, out ) ) + if( im_piocheck( in, out ) || + im_check_uncoded( "im_costra", in ) || + im_check_noncomplex( "im_costra", in ) ) return( -1 ); - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_costra", "%s", _( "not uncoded" ) ); - return( -1 ); - } - if( im_iscomplex( in ) ) { - im_error( "im_costra", "%s", _( "bad input type" ) ); - return( -1 ); - } /* Prepare output header. */ @@ -196,16 +190,10 @@ im_acostra( IMAGE *in, IMAGE *out ) { /* Check args. */ - if( im_piocheck( in, out ) ) + if( im_piocheck( in, out ) || + im_check_uncoded( "im_acostra", in ) || + im_check_noncomplex( "im_acostra", in ) ) return( -1 ); - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_acostra", "%s", _( "not uncoded" ) ); - return( -1 ); - } - if( im_iscomplex( in ) ) { - im_error( "im_acostra", "%s", _( "bad input type" ) ); - return( -1 ); - } /* Prepare output header. */ diff --git a/libsrc/arithmetic/im_cross_phase.c b/libsrc/arithmetic/im_cross_phase.c index 5aba17af..424cd912 100644 --- a/libsrc/arithmetic/im_cross_phase.c +++ b/libsrc/arithmetic/im_cross_phase.c @@ -133,26 +133,15 @@ int im_cross_phase( IMAGE *a, IMAGE *b, IMAGE *out ){ if( im_pincheck( a ) || im_pincheck( b ) || im_poutcheck( out )) return -1; - if( a-> Xsize != b-> Xsize || a-> Ysize != b-> Ysize ){ - im_error( FUNCTION_NAME, "not same size" ); + if( im_check_size( FUNCTION_NAME, a, b ) || + im_check_bands( FUNCTION_NAME, a, b ) || + im_check_uncoded( FUNCTION_NAME, a ) || + im_check_uncoded( FUNCTION_NAME, b ) || + im_check_format( FUNCTION_NAME, a, b ) || + im_check_complex( FUNCTION_NAME, a ) || + im_check_complex( FUNCTION_NAME, b ) ) return -1; - } - if( a-> Bands != b-> Bands ){ - im_error( FUNCTION_NAME, "numbers of bands differ" ); - return -1; - } - if( a-> Coding || b-> Coding ){ - im_error( FUNCTION_NAME, "not uncoded" ); - return -1; - } - if( a-> BandFmt != b-> BandFmt ){ - im_error( FUNCTION_NAME, "formats differ" ); - return -1; - } - if( IM_BANDFMT_COMPLEX != a-> BandFmt && IM_BANDFMT_DPCOMPLEX != a-> BandFmt ){ - im_error( FUNCTION_NAME, "not complex format" ); - return -1; - } + return im_cp_descv( out, a, b, NULL ) || im_wraptwo( a, b, out, IM_BANDFMT_COMPLEX == a-> BandFmt ? complex_phase_float : complex_phase_double, a, NULL ); } diff --git a/libsrc/arithmetic/im_deviate.c b/libsrc/arithmetic/im_deviate.c index addb7097..4e641d59 100644 --- a/libsrc/arithmetic/im_deviate.c +++ b/libsrc/arithmetic/im_deviate.c @@ -193,16 +193,10 @@ im_deviate( IMAGE *in, double *out ) /* Check our args. */ - if( im_pincheck( in ) ) + if( im_pincheck( in ) || + im_check_uncoded( "im_deviate", in ) || + im_check_noncomplex( "im_deviate", in ) ) return( -1 ); - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_deviate", "%s", _( "not uncoded" ) ); - return( -1 ); - } - if( im_iscomplex( in ) ) { - im_error( "im_deviate", "%s", _( "bad input type" ) ); - return( -1 ); - } /* Loop over input, summing pixels. */ @@ -211,9 +205,9 @@ im_deviate( IMAGE *in, double *out ) /* - NOTE: NR suggests a two-pass algorithm to minimise roundoff. - But that's too expensive for us :-( so do it the old one-pass - way. + NOTE: NR suggests a two-pass algorithm to minimise roundoff. + But that's too expensive for us :-( so do it the old one-pass + way. */ diff --git a/libsrc/arithmetic/im_divide.c b/libsrc/arithmetic/im_divide.c index c17755db..1c040e1e 100644 --- a/libsrc/arithmetic/im_divide.c +++ b/libsrc/arithmetic/im_divide.c @@ -173,19 +173,12 @@ divide_buffer( PEL **in, PEL *out, int width, IMAGE *im ) int im_divide( IMAGE *in1, IMAGE *in2, IMAGE *out ) { - /* Basic checks. - */ - if( im_piocheck( in1, out ) || im_pincheck( in2 ) ) + if( im_piocheck( in1, out ) || + im_pincheck( in2 ) || + im_check_bands_1orn( "im_divide", in1, in2 ) || + im_check_uncoded( "im_divide", in1 ) || + im_check_uncoded( "im_divide", in2 ) ) return( -1 ); - if( in1->Bands != in2->Bands && - (in1->Bands != 1 && in2->Bands != 1) ) { - im_error( "im_divide", "%s", _( "not same number of bands" ) ); - return( -1 ); - } - if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) { - im_error( "im_divide", "%s", _( "not uncoded" ) ); - return( -1 ); - } if( im_cp_descv( out, in1, in2, NULL ) ) return( -1 ); diff --git a/libsrc/arithmetic/im_expntra.c b/libsrc/arithmetic/im_expntra.c index 7a927c88..0c69b600 100644 --- a/libsrc/arithmetic/im_expntra.c +++ b/libsrc/arithmetic/im_expntra.c @@ -180,19 +180,10 @@ im_expntra_vec( IMAGE *in, IMAGE *out, int n, double *e ) /* Check args. */ - if( in->Coding != IM_CODING_NONE ) { - im_error( "im_expntra_vec", "%s", _( "not uncoded" ) ); + if( im_check_uncoded( "im_expntra_vec", in ) || + im_check_noncomplex( "im_expntra_vec", in ) || + im_check_vector( "im_expntra_vec", n, in ) ) return( -1 ); - } - if( im_iscomplex( in ) ) { - im_error( "im_expntra_vec", "%s", _( "not non-complex" ) ); - return( -1 ); - } - if( n != 1 && n != in->Bands ) { - im_error( "im_expntra_vec", - _( "not 1 or %d elements in vector" ), in->Bands ); - return( -1 ); - } /* Prepare output header. */ diff --git a/libsrc/iofuncs/predicate.c b/libsrc/iofuncs/predicate.c index c8042f83..cd79ca1c 100644 --- a/libsrc/iofuncs/predicate.c +++ b/libsrc/iofuncs/predicate.c @@ -26,6 +26,8 @@ * - cleanups * 22/5/08 * - image format stuff broken out + * 29/7/09 + * - check funcs added */ /* @@ -356,3 +358,97 @@ im_isvips( const char *filename ) return( 0 ); } + +int +im_check_uncoded( const char *domain, IMAGE *im ) +{ + if( im->Coding != IM_CODING_NONE ) { + im_error( domain, "%s", _( "image must be uncoded" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Bands != im2->Bands && + (im1->Bands != 1 && im2->Bands != 1) ) { + im_error( domain, "%s", + _( "images must have the same number of bands, " + "or one muct be single-band" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_noncomplex( const char *domain, IMAGE *im ) +{ + if( im_iscomplex( im ) ) { + im_error( domain, "%s", _( "image must be non-complex" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_complex( const char *domain, IMAGE *im ) +{ + if( !im_iscomplex( im ) ) { + im_error( domain, "%s", _( "image must be complex" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_size( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Xsize != im2->Xsize || im1->Ysize != im2->Ysize ) { + im_error( domain, "%s", _( "images must match in size" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_bands( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Bands != im2->Bands ) { + im_error( domain, "%s", + _( "images must have the same number of bands" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_format( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->BandFmt != im2->BandFmt ) { + im_error( domain, "%s", + _( "images must have the same band format" ) ); + return( -1 ); + } + + return( 0 ); +} + +int +im_check_vector( const char *domain, int n, IMAGE *im ) +{ + if( n != 1 && n != im->Bands ) { + im_error( domain, + _( "vector must have 1 or %d elements" ), im->Bands ); + return( -1 ); + } + + return( 0 ); +} diff --git a/libsrc/resample/nohalo1.cpp b/libsrc/resample/nohalo1.cpp index e540f042..6b62af30 100644 --- a/libsrc/resample/nohalo1.cpp +++ b/libsrc/resample/nohalo1.cpp @@ -315,7 +315,7 @@ nohalo1( const double uno_two, * absolute value) is taken to be the corresponding slope; if the * two consecutive pixel value differences don't have the same sign, * the corresponding slope is set to 0. In other words, apply minmod - * to comsecutive differences. + * to consecutive differences. */ /* * Dos(s) horizontal differences: