static int vips_scale_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsScale *scale = (VipsScale *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); double mx; double mn; if( VIPS_OBJECT_CLASS( vips_scale_parent_class )->build( object ) ) return( -1 ); if( vips_stats( scale->in, &t[0], NULL ) ) return( -1 ); mn = *VIPS_MATRIX( t[0], 0, 0 ); mx = *VIPS_MATRIX( t[0], 1, 0 ); if( mn == mx ) { /* Range of zero: just return black. */ if( vips_black( &t[1], scale->in->Xsize, scale->in->Ysize, "bands", scale->in->Bands, NULL ) || vips_image_write( t[1], conversion->out ) ) return( -1 ); } else if( scale->log ) { double f = 255.0 / log10( 1.0 + pow( mx, scale->exp ) ); if( vips_pow_const1( scale->in, &t[2], scale->exp, NULL ) || vips_linear1( t[2], &t[3], 1.0, 1.0, NULL ) || vips_log10( t[3], &t[4], NULL ) || vips_linear1( t[4], &t[5], f, 0.0, "uchar", TRUE, NULL ) || vips_image_write( t[5], conversion->out ) ) return( -1 ); } else { double f = 255.0 / (mx - mn); /* Add .5 to get round-to-nearest. */ double a = -(mn * f) + 0.5; if( vips_linear1( scale->in, &t[2], f, a, "uchar", TRUE, NULL ) || vips_image_write( t[2], conversion->out ) ) return( -1 ); } return( 0 ); }
/* Calculate sqrt(b1^2 + b2^2 ...) */ static int pythagoras( VipsSmartcrop *smartcrop, VipsImage *in, VipsImage **out ) { VipsImage **t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( smartcrop ), 2 * in->Bands + 1 ); int i; for( i = 0; i < in->Bands; i++ ) if( vips_extract_band( in, &t[i], i, NULL ) ) return( -1 ); for( i = 0; i < in->Bands; i++ ) if( vips_multiply( t[i], t[i], &t[i + in->Bands], NULL ) ) return( -1 ); if( vips_sum( &t[in->Bands], &t[2 * in->Bands], in->Bands, NULL ) || vips_pow_const1( t[2 * in->Bands], out, 0.5, NULL ) ) return( -1 ); return( 0 ); }