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 ); }
int vips__matrix_write( VipsImage *in, const char *filename ) { VipsImage *mask; FILE *fp; int x, y; if( vips_check_matrix( "vips2mask", in, &mask ) ) return( -1 ); if( !(fp = vips__file_open_write( filename, TRUE )) ) { g_object_unref( mask ); return( -1 ); } fprintf( fp, "%d %d ", mask->Xsize, mask->Ysize ); if( vips_image_get_typeof( mask, "scale" ) && vips_image_get_typeof( mask, "offset" ) ) fprintf( fp, "%g %g ", vips_image_get_scale( mask ), vips_image_get_offset( mask ) ); fprintf( fp, "\n" ); for( y = 0; y < mask->Ysize; y++ ) { for( x = 0; x < mask->Xsize; x++ ) fprintf( fp, "%g ", *VIPS_MATRIX( mask, x, y ) ); fprintf( fp, "\n" ); } g_object_unref( mask ); fclose( fp ); return( 0 ); }
static int vips__matrix_body( char *whitemap, VipsImage *out, FILE *fp ) { int x, y; for( y = 0; y < out->Ysize; y++ ) { for( x = 0; x < out->Xsize; x++ ) { int ch; double d; ch = read_ascii_double( fp, whitemap, &d ); if( ch == EOF || ch == '\n' ) { vips_error( "mask2vips", _( "line %d too short" ), y + 1 ); return( -1 ); } *VIPS_MATRIX( out, x, y ) = d; /* Deliberately don't check for line too long. */ } skip_line( fp ); } return( 0 ); }
int vips__matrix_write_file( VipsImage *in, FILE *fp ) { VipsImage *mask; int x, y; if( vips_check_matrix( "vips2mask", in, &mask ) ) return( -1 ); fprintf( fp, "%d %d ", mask->Xsize, mask->Ysize ); if( vips_image_get_typeof( mask, "scale" ) && vips_image_get_typeof( mask, "offset" ) ) fprintf( fp, "%g %g ", vips_image_get_scale( mask ), vips_image_get_offset( mask ) ); fprintf( fp, "\n" ); for( y = 0; y < mask->Ysize; y++ ) { for( x = 0; x < mask->Xsize; x++ ) fprintf( fp, "%g ", *VIPS_MATRIX( mask, x, y ) ); fprintf( fp, "\n" ); } g_object_unref( mask ); return( 0 ); }
return( 0 ); else return( -1 ); } static int vips_buildlut_build_init( VipsBuildlut *lut ) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( lut ); int y; int xlow, xhigh; /* Need xlow and xhigh to get the size of the LUT we build. */ xlow = xhigh = *VIPS_MATRIX( lut->mat, 0, 0 ); for( y = 0; y < lut->mat->Ysize; y++ ) { double v = *VIPS_MATRIX( lut->mat, 0, y ); /* Allow for being a bit off. */ if( abs( v - VIPS_RINT( v ) ) > 0.001 ) { vips_error( class->nickname, _( "x value row %d not an int" ), y ); return( -1 ); } v = VIPS_RINT( v ); if( v < xlow ) xlow = v;
static int vips_quadratic_gen( VipsRegion *or, void *vseq, void *a, void *b, gboolean *stop ) { VipsRegion *ir = (VipsRegion *) vseq; VipsQuadratic *quadratic = (VipsQuadratic *) b; VipsResample *resample = VIPS_RESAMPLE( quadratic ); VipsInterpolateMethod interpolate_fn = vips_interpolate_get_method( quadratic->interpolate ); /* @in is the enlarged image (borders on, after vips_embed()). Use * @resample->in for the original, not-expanded image. */ const VipsImage *in = (VipsImage *) a; const int ps = VIPS_IMAGE_SIZEOF_PEL( in ); double *vec = VIPS_MATRIX( quadratic->mat, 0, 0 ); int clip_width = resample->in->Xsize; int clip_height = resample->in->Ysize; int xlow = or->valid.left; int ylow = or->valid.top; int xhigh = VIPS_RECT_RIGHT( &or->valid ); int yhigh = VIPS_RECT_BOTTOM( &or->valid ); VipsPel *q; int xo, yo; /* output coordinates, dstimage */ int z; double fxi, fyi; /* input coordinates */ double dx, dy; /* xo derivative of input coord. */ double ddx, ddy; /* 2nd xo derivative of input coord. */ VipsRect image; image.left = 0; image.top = 0; image.width = in->Xsize; image.height = in->Ysize; if( vips_region_image( ir, &image ) ) return( -1 ); for( yo = ylow; yo < yhigh; yo++ ) { fxi = 0.0; fyi = 0.0; dx = 0.0; dy = 0.0; ddx = 0.0; ddy = 0.0; switch( quadratic->order ) { case 3: fxi += vec[10] * yo * yo + vec[8] * xlow * xlow; fyi += vec[11] * yo * yo + vec[9] * xlow * xlow; dx += vec[8]; ddx += vec[8] * 2.0; dy += vec[9]; ddy += vec[9] * 2.0; case 2: fxi += vec[6] * xlow * yo; fyi += vec[7] * xlow * yo; dx += vec[6] * yo; dy += vec[7] * yo; case 1: fxi += vec[4] * yo + vec[2] * xlow; fyi += vec[5] * yo + vec[3] * xlow; dx += vec[2]; dy += vec[3]; case 0: fxi += vec[0]; fyi += vec[1]; break; default: g_assert( 0 ); return( -7 ); } printf( "dx = %g, dy = %g\n", dx, dy ); q = VIPS_REGION_ADDR( or, xlow, yo ); for( xo = xlow; xo < xhigh; xo++ ) { int xi, yi; xi = fxi; yi = fyi; /* Clipping! */ if( xi < 0 || yi < 0 || xi >= clip_width || yi >= clip_height ) { for( z = 0; z < ps; z++ ) q[z] = 0; } else interpolate_fn( quadratic->interpolate, q, ir, fxi, fyi ); q += ps; fxi += dx; fyi += dy; if( quadratic->order > 2 ) { dx += ddx; dy += ddy; } } } return( 0 ); }