diff --git a/ChangeLog b/ChangeLog index 083c278b..ba8b4e76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ - configure spots support for "restrict" - reset dcm:display-range on magick read to help DICOM - saner im_buildlut() behaviour +- added im_gauss_imask_sep() 3/3/09 started 7.17.2 - im_magick2vips.c: allow funky bit depths, like 14 (thanks Mikkel) diff --git a/include/vips/proto.h b/include/vips/proto.h index eff14860..53dd15ba 100644 --- a/include/vips/proto.h +++ b/include/vips/proto.h @@ -234,6 +234,7 @@ DOUBLEMASK *im_rotate_dmask45( DOUBLEMASK *, const char * ); INTMASK *im_log_imask( const char *, double, double ); DOUBLEMASK *im_log_dmask( const char *, double, double ); INTMASK *im_gauss_imask( const char *, double, double ); +INTMASK *im_gauss_imask_sep( const char *, double, double ); DOUBLEMASK *im_gauss_dmask( const char *, double, double ); int im_rank( IMAGE *, IMAGE *, int, int, int ); diff --git a/libsrc/convolution/convol_dispatch.c b/libsrc/convolution/convol_dispatch.c index dde2e737..a5b16d90 100644 --- a/libsrc/convolution/convol_dispatch.c +++ b/libsrc/convolution/convol_dispatch.c @@ -672,6 +672,33 @@ static im_function gauss_imask_desc = { gauss_imask_args /* Arg list */ }; +/* Call im_gauss_imask_sep via arg vector. + */ +static int +gauss_imask_sep_vec( im_object *argv ) +{ + im_mask_object *mo = argv[0]; + double sigma = *((double *) argv[1]); + double min_amp = *((double *) argv[2]); + + if( !(mo->mask = + im_gauss_imask_sep( mo->name, sigma, min_amp )) ) + return( -1 ); + + return( 0 ); +} + +/* Description of im_gauss_imask_sep. + */ +static im_function gauss_imask_sep_desc = { + "im_gauss_imask_sep", /* Name */ + "generate separable gaussian INTMASK", + 0, /* Flags */ + gauss_imask_sep_vec, /* Dispatch function */ + IM_NUMBER( gauss_imask_args ), /* Size of arg list */ + gauss_imask_args /* Arg list */ +}; + /* Args for im_gaussnoise. */ static im_arg_desc gaussnoise_args[] = { @@ -1347,6 +1374,7 @@ static im_function *convol_list[] = { &fastcor_raw_desc, &gauss_dmask_desc, &gauss_imask_desc, + &gauss_imask_sep_desc, &gaussnoise_desc, &grad_x_desc, &grad_y_desc, diff --git a/libsrc/convolution/im_gaussmasks.c b/libsrc/convolution/im_gaussmasks.c index 3402ccab..c752daea 100644 --- a/libsrc/convolution/im_gaussmasks.c +++ b/libsrc/convolution/im_gaussmasks.c @@ -27,6 +27,9 @@ * - ansified, mem leaks plugged * 20/11/98 JC * - mask too large check added + * 18/3/09 + * - bumped max mask size *40 + * - added _sep variant */ /* @@ -69,7 +72,7 @@ #include #endif /*WITH_DMALLOC*/ -#define IM_MAXMASK 256 +#define IM_MAXMASK 5000 DOUBLEMASK * im_gauss_dmask( const char *filename, double sigma, double min_ampl ) @@ -96,7 +99,7 @@ im_gauss_dmask( const char *filename, double sigma, double min_ampl ) break; } if( x == max_x ) { - im_errormsg( "im_gauss_dmask: mask too large" ); + im_error( "im_gauss_dmask", "%s", _( "mask too large" ) ); return( NULL ); } @@ -180,3 +183,28 @@ im_gauss_imask( const char *filename, double sigma, double min_amplitude ) return( im ) ; } + +/* Just return the central line of the mask. This helps nip, which really + * struggles with large matrix manipulations. + */ +INTMASK * +im_gauss_imask_sep( const char *filename, double sigma, double min_amplitude ) +{ + INTMASK *im; + INTMASK *im2; + int i; + + if( !(im = im_gauss_imask( filename, sigma, min_amplitude )) ) + return( NULL ); + if( !(im2 = im_create_imask( filename, im->xsize, 1 )) ) { + im_free_imask( im ); + return( NULL ); + } + + for( i = 0; i < im->xsize; i++ ) + im2->coeff[i] = im->coeff[i + im->xsize * (im->ysize / 2)]; + + im_free_imask( im ); + + return( im2 ) ; +}