static int vips_min_build( VipsObject *object ) { VipsStatistic *statistic = VIPS_STATISTIC( object ); VipsMin *min = (VipsMin *) object; if( VIPS_OBJECT_CLASS( vips_min_parent_class )->build( object ) ) return( -1 ); /* Don't set if there's no value (eg. if every pixel is NaN). This * will trigger an error later. */ if( min->set ) { double m; /* For speed we accumulate min^2 for complex. */ m = min->min; if( vips_bandfmt_iscomplex( vips_image_get_format( statistic->in ) ) ) m = sqrt( m ); /* We have to set the props via g_object_set() to stop vips * complaining they are unset. */ g_object_set( min, "out", m, "x", min->x, "y", min->y, NULL ); } return( 0 ); }
static int vips_min_build( VipsObject *object ) { VipsStatistic *statistic = VIPS_STATISTIC( object ); VipsMin *min = (VipsMin *) object; double m; if( VIPS_OBJECT_CLASS( vips_min_parent_class )->build( object ) ) return( -1 ); /* For speed we accumulate min^2 for complex. */ m = min->min; if( vips_bandfmt_iscomplex( vips_image_get_format( statistic->in ) ) ) m = sqrt( m ); /* We have to set the props via g_object_set() to stop vips * complaining they are unset. */ g_object_set( min, "out", m, "x", min->x, "y", min->y, NULL ); return( 0 ); }
/* Return the position of the first non-zero pel from the bottom. */ static int find_bot( REGION *ir, int *pos, int x, int y, int h ) { VipsPel *pr = IM_REGION_ADDR( ir, x, y ); IMAGE *im = ir->im; int ls = IM_REGION_LSKIP( ir ) / IM_IMAGE_SIZEOF_ELEMENT( ir->im ); int b = im->Bands; int i, j; /* Double the number of bands in a complex. */ if( vips_bandfmt_iscomplex( im->BandFmt ) ) b *= 2; /* Search for the first non-zero band element from the top edge of the image. */ #define rsearch( TYPE ) { \ TYPE *p = (TYPE *) pr + (h - 1) * ls; \ \ for( i = h - 1; i >= 0; i-- ) { \ for( j = 0; j < b; j++ ) \ if( p[j] ) \ break; \ if( j < b ) \ break; \ \ p -= ls; \ } \ } switch( im->BandFmt ) { case IM_BANDFMT_UCHAR: rsearch( unsigned char ); break; case IM_BANDFMT_CHAR: rsearch( signed char ); break; case IM_BANDFMT_USHORT: rsearch( unsigned short ); break; case IM_BANDFMT_SHORT: rsearch( signed short ); break; case IM_BANDFMT_UINT: rsearch( unsigned int ); break; case IM_BANDFMT_INT: rsearch( signed int ); break; case IM_BANDFMT_FLOAT: rsearch( float ); break; case IM_BANDFMT_DOUBLE: rsearch( double ); break; case IM_BANDFMT_COMPLEX:rsearch( float ); break; case IM_BANDFMT_DPCOMPLEX:rsearch( double ); break; default: im_error( "im_tbmerge", "%s", _( "internal error" ) ); return( -1 ); } *pos = y + i; return( 0 ); }
/* Return the position of the first non-zero pel from the right. */ static int find_last( REGION *ir, int *pos, int x, int y, int w ) { PEL *pr = (PEL *) IM_REGION_ADDR( ir, x, y ); IMAGE *im = ir->im; int ne = w * im->Bands; int i; /* Double the number of bands in a complex. */ if( vips_bandfmt_iscomplex( im->BandFmt ) ) ne *= 2; /* Search for the first non-zero band element from the right. */ #define rsearch( TYPE ) { \ TYPE *p = (TYPE *) pr; \ \ for( i = ne - 1; i >= 0; i-- )\ if( p[i] )\ break;\ } switch( im->BandFmt ) { case IM_BANDFMT_UCHAR: rsearch( unsigned char ); break; case IM_BANDFMT_CHAR: rsearch( signed char ); break; case IM_BANDFMT_USHORT: rsearch( unsigned short ); break; case IM_BANDFMT_SHORT: rsearch( signed short ); break; case IM_BANDFMT_UINT: rsearch( unsigned int ); break; case IM_BANDFMT_INT: rsearch( signed int ); break; case IM_BANDFMT_FLOAT: rsearch( float ); break; case IM_BANDFMT_DOUBLE: rsearch( double ); break; case IM_BANDFMT_COMPLEX:rsearch( float ); break; case IM_BANDFMT_DPCOMPLEX:rsearch( double ); break; default: im_error( "im_lrmerge", "%s", _( "internal error" ) ); return( -1 ); } /* i is first non-zero band element, we want first non-zero pixel. */ *pos = x + i / im->Bands; return( 0 ); }
static void vips_round_buffer( VipsArithmetic *arithmetic, VipsPel *out, VipsPel **in, int width ) { VipsRound *round = (VipsRound *) arithmetic; VipsImage *im = arithmetic->ready[0]; /* Complex just doubles the size. */ const int sz = width * im->Bands * (vips_bandfmt_iscomplex( im->BandFmt ) ? 2 : 1); int x; switch( round->round ) { case VIPS_OPERATION_ROUND_RINT: SWITCH( VIPS_RINT ); break; case VIPS_OPERATION_ROUND_CEIL: SWITCH( ceil ); break; case VIPS_OPERATION_ROUND_FLOOR: SWITCH( floor ); break; default: g_assert( 0 ); } }
static void vips_hist_cum_process( VipsHistogram *histogram, VipsPel *out, VipsPel **in, int width ) { const int bands = vips_image_get_bands( histogram->ready[0] ); const int nb = vips_bandfmt_iscomplex( histogram->ready[0]->BandFmt ) ? bands * 2 : bands; int mx = width * nb; int x, b; switch( vips_image_get_format( histogram->ready[0] ) ) { case VIPS_FORMAT_CHAR: ACCUMULATE( signed char, signed int ); break; case VIPS_FORMAT_UCHAR: ACCUMULATE( unsigned char, unsigned int ); break; case VIPS_FORMAT_SHORT: ACCUMULATE( signed short, signed int ); break; case VIPS_FORMAT_USHORT: ACCUMULATE( unsigned short, unsigned int ); break; case VIPS_FORMAT_INT: ACCUMULATE( signed int, signed int ); break; case VIPS_FORMAT_UINT: ACCUMULATE( unsigned int, unsigned int ); break; case VIPS_FORMAT_FLOAT: case VIPS_FORMAT_COMPLEX: ACCUMULATE( float, float ); break; case VIPS_FORMAT_DOUBLE: case VIPS_FORMAT_DPCOMPLEX: ACCUMULATE( double, double ); break; default: g_assert( 0 ); } }
static void vips_bandmean_buffer( VipsBandary *bandary, VipsPel *out, VipsPel **in, int width ) { VipsImage *im = bandary->ready[0]; const int bands = im->Bands; const int sz = width * (vips_bandfmt_iscomplex( im->BandFmt ) ? 2 : 1); int i, j; switch( vips_image_get_format( im ) ) { case VIPS_FORMAT_CHAR: SILOOP( signed char, int ); break; case VIPS_FORMAT_UCHAR: UILOOP( unsigned char, unsigned int ); break; case VIPS_FORMAT_SHORT: SILOOP( signed short, int ); break; case VIPS_FORMAT_USHORT: UILOOP( unsigned short, unsigned int ); break; case VIPS_FORMAT_INT: SILOOP( signed int, int ); break; case VIPS_FORMAT_UINT: UILOOP( unsigned int, unsigned int ); break; case VIPS_FORMAT_FLOAT: FLOOP( float ); break; case VIPS_FORMAT_DOUBLE: FLOOP( double ); break; case VIPS_FORMAT_COMPLEX: FLOOP( float ); break; case VIPS_FORMAT_DPCOMPLEX: FLOOP( double ); break; default: g_assert( 0 ); } }
gboolean im_iscomplex( IMAGE *im ) { return( vips_bandfmt_iscomplex( im->BandFmt ) ); }
const double relative_x = absolute_x - ix; const double relative_y = absolute_y - iy; /* * VIPS versions of Nicolas's pixel addressing values. */ const int lskip = VIPS_REGION_LSKIP( in ) / VIPS_IMAGE_SIZEOF_ELEMENT( in->im ); /* * Double the bands for complex images to account for the real and * imaginary parts being computed independently: */ const int actual_bands = in->im->Bands; const int bands = vips_bandfmt_iscomplex( in->im->BandFmt ) ? 2 * actual_bands : actual_bands; /* Confirm that absolute_x and absolute_y are >= 1, see above. */ g_assert( absolute_x >= 1.0 ); g_assert( absolute_y >= 1.0 ); switch( in->im->BandFmt ) { case VIPS_FORMAT_UCHAR: CALL( unsigned char, nosign ); break; case VIPS_FORMAT_CHAR: CALL( signed char, withsign ); break;
/** * im_linreg: * @ins: NULL-terminated array of input images * @out: results of analysis * @xs: X position of each image (pixel value is Y) * * Function to find perform pixelwise linear regression on an array of * single band images. The output is a seven-band douuble image * * TODO: figure out how this works and fix up these docs! */ int im_linreg( IMAGE **ins, IMAGE *out, double *xs ){ #define FUNCTION_NAME "im_linreg" int n; x_set *x_vals; if( im_poutcheck( out ) ) return( -1 ); for( n= 0; ins[ n ]; ++n ){ /* if( ! isfinite( xs[ n ] ) ){ im_error( FUNCTION_NAME, "invalid argument" ); return( -1 ); } */ if( im_pincheck( ins[ n ] ) ) return( -1 ); if( 1 != ins[ n ]-> Bands ){ im_error( FUNCTION_NAME, "image is not single band" ); return( -1 ); } if( ins[ n ]-> Coding ){ im_error( FUNCTION_NAME, "image is not uncoded" ); return( -1 ); } if( n ){ if( ins[ n ]-> BandFmt != ins[ 0 ]-> BandFmt ){ im_error( FUNCTION_NAME, "image band formats differ" ); return( -1 ); } } else { if( vips_bandfmt_iscomplex( ins[ 0 ]->BandFmt ) ){ im_error( FUNCTION_NAME, "image has non-scalar band format" ); return( -1 ); } } if( n && ( ins[ n ]-> Xsize != ins[ 0 ]-> Xsize || ins[ n ]-> Ysize != ins[ 0 ]-> Ysize ) ){ im_error( FUNCTION_NAME, "image sizes differ" ); return( -1 ); } } if( n < 3 ){ im_error( FUNCTION_NAME, "not enough input images" ); return( -1 ); } if( im_cp_desc_array( out, ins ) ) return( -1 ); out-> Bands= 7; out-> BandFmt= IM_BANDFMT_DOUBLE; out-> Type= 0; if( im_demand_hint_array( out, IM_THINSTRIP, ins ) ) return( -1 ); x_vals= x_anal( out, xs, n ); if( ! x_vals ) return( -1 ); switch( ins[ 0 ]-> BandFmt ){ #define LINREG_RET( TYPE ) return im_generate( out, linreg_start_ ## TYPE, linreg_gen_ ## TYPE, linreg_stop_ ## TYPE, ins, x_vals ) case IM_BANDFMT_CHAR: LINREG_RET( gint8 ); case IM_BANDFMT_UCHAR: LINREG_RET( guint8 ); case IM_BANDFMT_SHORT: LINREG_RET( gint16 ); case IM_BANDFMT_USHORT: LINREG_RET( guint16 ); case IM_BANDFMT_INT: LINREG_RET( gint32 ); case IM_BANDFMT_UINT: LINREG_RET( guint32 ); case IM_BANDFMT_FLOAT: LINREG_RET( float ); case IM_BANDFMT_DOUBLE: LINREG_RET( double ); default: /* keep -Wall happy */ return( -1 ); } #undef FUNCTION_NAME }