Пример #1
0
VipsImage *
vips__matrix_read_file( FILE *fp )
{
    char whitemap[256];
    int i;
    char *p;
    int width;
    int height;
    double scale;
    double offset;
    VipsImage *out;

    for( i = 0; i < 256; i++ )
        whitemap[i] = 0;
    for( p = WHITESPACE; *p; p++ )
        whitemap[(int) *p] = 1;

    if( vips__matrix_header( whitemap, fp,
                             &width, &height, &scale, &offset ) )
        return( NULL );

    if( !(out = vips_image_new_matrix( width, height )) )
        return( NULL );
    vips_image_set_double( out, "scale", scale );
    vips_image_set_double( out, "offset", offset );

    if( vips__matrix_body( whitemap, out, fp ) ) {
        g_object_unref( out );
        return( NULL );
    }

    return( out );
}
Пример #2
0
int 
main( int argc, char **argv )
{
        VipsImage *global;
        VipsImage **t;

        if( VIPS_INIT( argv[0] ) )
                return( -1 );

        global = vips_image_new();
        t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( global ), 5 );

	VipsInterpolate *interp = vips_interpolate_new( "bilinear" );

        if( !(t[0] = vips_image_new_from_file( argv[1],
                "access", VIPS_ACCESS_SEQUENTIAL,
                NULL )) )
                vips_error_exit( NULL );

        t[1] = vips_image_new_matrixv( 3, 3, 
                -1.0, -1.0, -1.0, 
                -1.0, 16.0, -1.0,
                -1.0, -1.0, -1.0 );
        vips_image_set_double( t[1], "scale", 8 );

        if( vips_extract_area( t[0], &t[2], 
                100, 100, t[0]->Xsize - 200, t[0]->Ysize - 200, NULL ) ||
                vips_similarity( t[2], &t[3], 
			"scale", 0.9, 
			"interpolate", interp, 
			NULL ) ||
                vips_conv( t[3], &t[4], t[1], NULL ) ||
                vips_image_write_to_file( t[4], argv[2], NULL ) )
                vips_error_exit( NULL ); 

        g_object_unref( global );
        g_object_unref( interp );

        return( 0 );
}
Пример #3
0
/* Some interpolators look a little soft, so we have an optional sharpening
 * stage.
 */
static VipsImage *
thumbnail_sharpen( VipsObject *process )
{
	VipsImage *mask;

	if( strcmp( convolution_mask, "none" ) == 0 ) 
		mask = NULL; 
	else if( strcmp( convolution_mask, "mild" ) == 0 ) {
		mask = vips_image_new_matrixv( 3, 3,
			-1.0, -1.0, -1.0,
			-1.0, 32.0, -1.0,
			-1.0, -1.0, -1.0 );
		vips_image_set_double( mask, "scale", 24 );
	}
	else
		if( !(mask = 
			vips_image_new_from_file( convolution_mask, NULL )) )
			vips_error_exit( "unable to load sharpen mask" ); 

	if( mask )
		vips_object_local( process, mask );

	return( mask );
}
Пример #4
0
static int
read_header( FILE *fp, VipsImage *out, int *bits, int *ascii, int *msb_first )
{
	int width, height, bands; 
	VipsBandFormat format;
	VipsInterpretation interpretation; 
	int index;
	char buf[MAX_THING];

	/* Characteristics, indexed by ppm type.
	 */
	static int lookup_bits[] = {
		1, 8, 8, 1, 8, 8, 32, 32
	};
	static int lookup_bands[] = {
		1, 1, 3, 1, 1, 3, 3, 1
	};
	static int lookup_ascii[] = {
		1, 1, 1, 0, 0, 0, 0, 0
	};

	/* Read in the magic number.
	 */
	buf[0] = fgetc( fp );
	buf[1] = fgetc( fp );
	buf[2] = '\0';

	for( index = 0; index < VIPS_NUMBER( magic_names ); index++ )
		if( strcmp( magic_names[index], buf ) == 0 ) 
			break;
	if( index == VIPS_NUMBER( magic_names ) ) {
		vips_error( "ppm2vips", "%s", _( "bad magic number" ) );
		return( -1 );
	}
	*bits = lookup_bits[index];
	bands = lookup_bands[index];
	*ascii = lookup_ascii[index];

	/* Default ... can be changed below for PFM images.
	 */
	*msb_first = 0;

	/* Read in size.
	 */
	if( read_int( fp, &width ) ||
		read_int( fp, &height ) )
		return( -1 );

	/* Read in max value / scale for >1 bit images.
	 */
	if( *bits > 1 ) {
		if( index == 6 || index == 7 ) {
			float scale;

			if( read_float( fp, &scale ) )
				return( -1 );

			/* Scale > 0 means big-endian.
			 */
			*msb_first = scale > 0;
			vips_image_set_double( out, 
				"pfm-scale", fabs( scale ) );
		}
		else {
			int max_value;

			if( read_int( fp, &max_value ) )
				return( -1 );

			if( max_value > 255 )
				*bits = 16;
			if( max_value > 65535 )
				*bits = 32;
		}
	}

	/* For binary images, there is always exactly 1 more whitespace
	 * character before the data starts.
	 */
	if( !*ascii && !isspace( fgetc( fp ) ) ) {
		vips_error( "ppm2vips", "%s", 
			_( "not whitespace before start of binary data" ) );
		return( -1 );
	}

	/* Choose a VIPS bandfmt.
	 */
	switch( *bits ) {
	case 1:
	case 8:
		format = VIPS_FORMAT_UCHAR;
		break;

	case 16:
		format = VIPS_FORMAT_USHORT;
		break;

	case 32:
		if( index == 6 || index == 7 )
			format = VIPS_FORMAT_FLOAT;
		else
			format = VIPS_FORMAT_UINT;
		break;

	default:
		g_assert( 0 );

		/* Keep -Wall happy.
		 */
		return( 0 );
	}

	if( bands == 1 ) {
		if( format == VIPS_FORMAT_USHORT )
			interpretation = VIPS_INTERPRETATION_GREY16;
		else
			interpretation = VIPS_INTERPRETATION_B_W;
	}
	else {
		if( format == VIPS_FORMAT_USHORT )
			interpretation = VIPS_INTERPRETATION_RGB16;
		else if( format == VIPS_FORMAT_UINT )
			interpretation = VIPS_INTERPRETATION_RGB;
		else 
			interpretation = VIPS_INTERPRETATION_sRGB;
	}

	vips_image_init_fields( out,
		width, height, bands, format, 
		VIPS_CODING_NONE, interpretation, 1.0, 1.0 );

	return( 0 );
}
Пример #5
0
static int
vips_resize_build( VipsObject *object )
{
	VipsResample *resample = VIPS_RESAMPLE( object );
	VipsResize *resize = (VipsResize *) object;

	VipsImage **t = (VipsImage **) 
		vips_object_local_array( object, 7 );

	VipsImage *in;
	int window_size;
	int int_shrink;
	int int_shrink_width;
	double residual;
	double sigma;

	if( VIPS_OBJECT_CLASS( vips_resize_parent_class )->build( object ) )
		return( -1 );

	if( !vips_object_argument_isset( object, "interpolate" ) ) {
		VipsInterpolate *interpolate;
		char *nick;

		if( vips_type_find( "VipsInterpolate", "bicubic" ) )
			nick = "bicubic";
		else
			nick = "bilinear";
		interpolate = vips_interpolate_new( nick );
		g_object_set( object, "interpolate", interpolate, NULL ); 
		VIPS_UNREF( interpolate ); 
	}

	in = resample->in;

	window_size = resize->interpolate ? 
		vips_interpolate_get_window_size( resize->interpolate ) : 2;

	/* If the factor is > 1.0, we need to zoom rather than shrink.
	 * Just set the int part to 1 in this case.
	 */
	int_shrink = resize->scale > 1.0 ? 1 : floor( 1.0 / resize->scale );

	/* We want to shrink by less for interpolators with larger windows.
	 */
	int_shrink = VIPS_MAX( 1,
		int_shrink / VIPS_MAX( 1, window_size / 2 ) );

	/* Size after int shrink.
	 */
	int_shrink_width = in->Xsize / int_shrink;

	/* Therefore residual scale factor is.
	 */
	residual = (in->Xsize * resize->scale) / int_shrink_width;

	/* A copy for enlarge resize.
	 */
	if( vips_shrink( in, &t[0], int_shrink, int_shrink, NULL ) )
		return( -1 );
	in = t[0];

	/* We want to make sure we read the image sequentially.
	 * However, the convolution we may be doing later will force us 
	 * into SMALLTILE or maybe FATSTRIP mode and that will break
	 * sequentiality.
	 *
	 * So ... read into a cache where tiles are scanlines, and make sure
	 * we keep enough scanlines to be able to serve a line of tiles.
	 *
	 * We use a threaded tilecache to avoid a deadlock: suppose thread1,
	 * evaluating the top block of the output, is delayed, and thread2, 
	 * evaluating the second block, gets here first (this can happen on 
	 * a heavily-loaded system). 
	 *
	 * With an unthreaded tilecache (as we had before), thread2 will get
	 * the cache lock and start evaling the second block of the shrink. 
	 * When it reaches the png reader it will stall until the first block 
	 * has been used ... but it never will, since thread1 will block on 
	 * this cache lock. 
	 */
	if( int_shrink > 1 ) { 
		int tile_width;
		int tile_height;
		int nlines;

		vips_get_tile_size( in, 
			&tile_width, &tile_height, &nlines );
		if( vips_tilecache( in, &t[6], 
			"tile_width", in->Xsize,
			"tile_height", 10,
			"max_tiles", 1 + (nlines * 2) / 10,
			"access", VIPS_ACCESS_SEQUENTIAL,
			"threaded", TRUE, 
			NULL ) )
			return( -1 );
		in = t[6];
	}

	/* If the final affine will be doing a large downsample, we can get 
	 * nasty aliasing on hard edges. Blur before affine to smooth this out.
	 *
	 * Don't blur for very small shrinks, blur with radius 1 for x1.5
	 * shrinks, blur radius 2 for x2.5 shrinks and above, etc.
	 */
	sigma = ((1.0 / residual) - 0.5) / 1.5;
	if( residual < 1.0 &&
		sigma > 0.1 ) { 
		if( vips_gaussblur( in, &t[2], sigma, NULL ) )
			return( -1 );
		in = t[2];
	}

	if( vips_affine( in, &t[3], residual, 0, 0, residual, 
		"interpolate", resize->interpolate,
		"idx", resize->idx,
		"idy", resize->idy,
		NULL ) )  
		return( -1 );
	in = t[3];

	/* If we are upsampling, don't sharpen.
	 */
	if( int_shrink > 1 ) { 
		t[5] = vips_image_new_matrixv( 3, 3,
			-1.0, -1.0, -1.0,
			-1.0, 32.0, -1.0,
			-1.0, -1.0, -1.0 );
		vips_image_set_double( t[5], "scale", 24 );

		if( vips_conv( in, &t[4], t[5], NULL ) ) 
			return( -1 );
		in = t[4];
	}

	if( vips_image_write( in, resample->out ) )
		return( -1 ); 

	return( 0 );
}