Exemple #1
0
/**
 * im_fits2vips:
 * @filename: file to load
 * @out: image to write to
 *
 * Read a FITS image file into a VIPS image. 
 *
 * See also: im_vips2fits(), #VipsFormat.
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_fits2vips( const char *filename, VipsImage *out )
{
	VipsImage *t;
	int n_bands;

	VIPS_DEBUG_MSG( "im_fits2vips: reading \"%s\"\n", filename );

	/* fits is naturally a band-separated format. For single-band images,
	 * we can just read out. For many bands, we read each band out
	 * separately then join them.
	 */

	if( !(t = vips_image_new()) ||
		vips_object_local( out, t ) ||
		fits2vips_header( filename, t ) )
		return( -1 );
	n_bands = t->Bands;

	if( n_bands == 1 ) {
		if( !(t = vips_image_new()) ||
			vips_object_local( out, t ) ||
			fits2vips( filename, t, 0 ) )
			return( -1 );
	}
	else {
		VipsImage *acc;
		int i;

		acc = NULL;
		for( i = 0; i < n_bands; i++ ) {
			if( !(t = vips_image_new()) ||
				vips_object_local( out, t ) ||
				fits2vips( filename, t, i ) )
				return( -1 );

			if( !acc )
				acc = t;
			else {
				VipsImage *t2;

				if( !(t2 = vips_image_new()) ||
					vips_object_local( out, t2 ) ||
					im_bandjoin( acc, t, t2 ) )
					return( -1 );
				acc = t2;
			}
		}

		t = acc;
	}

	/* fits has inverted y.
	 */
	if( im_flipver( t, out ) )
		return( -1 );

	return( 0 );
}
static int
vips_sequential_build( VipsObject *object )
{
	VipsConversion *conversion = VIPS_CONVERSION( object );
	VipsSequential *sequential = (VipsSequential *) object;

	VipsImage *t;

	VIPS_DEBUG_MSG( "vips_sequential_build\n" );

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

	if( vips_image_pio_input( sequential->in ) )
		return( -1 );

	if( vips_linecache( sequential->in, &t, 
		"tile_height", sequential->tile_height,
		"access", sequential->access,
		NULL ) )
		return( -1 );

	vips_object_local( object, t ); 

	if( vips_image_pipelinev( conversion->out, 
		VIPS_DEMAND_STYLE_THINSTRIP, t, NULL ) )
		return( -1 );
	if( vips_image_generate( conversion->out,
		vips_start_one, vips_sequential_generate, vips_stop_one, 
		t, sequential ) )
		return( -1 );

	return( 0 );
}
Exemple #3
0
int
vips__openslide_read_associated( const char *filename, VipsImage *out, 
	const char *associated )
{
	ReadSlide *rslide;
	VipsImage *raw;
	const char *error;

	VIPS_DEBUG_MSG( "vips__openslide_read_associated: %s %s\n", 
		filename, associated );

	/* Memory buffer. Get associated directly to this, then copy to out.
	 */
	raw = vips_image_new_buffer();
	vips_object_local( out, raw );

	if( !(rslide = readslide_new( filename, raw, 0, associated )) ||
		vips_image_write_prepare( raw ) )
		return( -1 );
	openslide_read_associated_image( rslide->osr, rslide->associated, 
		(uint32_t *) VIPS_IMAGE_ADDR( raw, 0, 0 ) );
	error = openslide_get_error( rslide->osr );
	if( error ) {
		vips_error( "openslide2vips",
			_( "reading associated image: %s" ), error );
		return( -1 );
	}

	if( vips_image_write( raw, out ) ) 
		return( -1 );

	return( 0 );
}
Exemple #4
0
/* Just for compatibility. New code should use vips_object_local() directly.
 */
VipsImage *
im_open_local( VipsImage *parent, 
	const char *filename, const char *mode )
{
	VipsImage *image;

	if( !(image = im_open( filename, mode )) )
		return( NULL );
	vips_object_local( parent, image );

	return( image );
}
Exemple #5
0
/* Open an image, returning the best version of that image for thumbnailing. 
 *
 * libjpeg supports fast shrink-on-read, so if we have a JPEG, we can ask 
 * VIPS to load a lower resolution version.
 */
static VipsImage *
thumbnail_open( VipsObject *process, const char *filename )
{
	const char *loader;
	VipsImage *im;

	vips_info( "vipsthumbnail", "thumbnailing %s", filename );

	if( linear_processing )
		vips_info( "vipsthumbnail", "linear mode" ); 

	if( !(loader = vips_foreign_find_load( filename )) )
		return( NULL );

	vips_info( "vipsthumbnail", "selected loader is %s", loader ); 

	if( strcmp( loader, "VipsForeignLoadJpegFile" ) == 0 ) {
		int jpegshrink;

		/* This will just read in the header and is quick.
		 */
		if( !(im = vips_image_new_from_file( filename, NULL )) )
			return( NULL );

		jpegshrink = thumbnail_find_jpegshrink( im );

		g_object_unref( im );

		vips_info( "vipsthumbnail", 
			"loading jpeg with factor %d pre-shrink", 
			jpegshrink ); 

		if( !(im = vips_image_new_from_file( filename, 
			"access", VIPS_ACCESS_SEQUENTIAL,
			"shrink", jpegshrink,
			NULL )) )
			return( NULL );
	}
	else {
		/* All other formats.
		 */
		if( !(im = vips_image_new_from_file( filename, 
			"access", VIPS_ACCESS_SEQUENTIAL,
			NULL )) )
			return( NULL );
	}

	vips_object_local( process, im );

	return( im ); 
}
Exemple #6
0
static VipsInterpolate *
thumbnail_interpolator( VipsObject *process, VipsImage *in )
{
	double residual;
	VipsInterpolate *interp;

	calculate_shrink( in, &residual );

	/* For images smaller than the thumbnail, we upscale with nearest
	 * neighbor. Otherwise we makes thumbnails that look fuzzy and awful.
	 */
	if( !(interp = VIPS_INTERPOLATE( vips_object_new_from_string( 
		g_type_class_ref( VIPS_TYPE_INTERPOLATE ), 
		residual > 1.0 ? "nearest" : interpolator ) )) )
		return( NULL );

	vips_object_local( process, interp );

	return( interp );
}
Exemple #7
0
int
vips__openslide_read( const char *filename, VipsImage *out, int layer )
{
	ReadSlide *rslide;
	VipsImage *raw;
	VipsImage *t;

	VIPS_DEBUG_MSG( "vips__openslide_read: %s %d\n", 
		filename, layer );

	/* Tile cache: keep enough for two complete rows of tiles. OpenSlide
	 * has its own tile cache, but it's not large enough for a complete
	 * scan line.
	 */
	raw = vips_image_new();
	vips_object_local( out, raw );

	if( !(rslide = readslide_new( filename, raw, layer, NULL )) )
		return( -1 );

	if( vips_image_generate( raw, 
		NULL, vips__openslide_generate, NULL, rslide, NULL ) )
		return( -1 );

	/* Copy to out, adding a cache. Enough tiles for a complete row, plus
	 * 50%.
	 */
	if( vips_tilecache( raw, &t, 
		"tile_width", TILE_WIDTH, 
		"tile_height", TILE_WIDTH,
		"max_tiles", (int) (1.5 * (1 + raw->Xsize / TILE_WIDTH)),
		NULL ) ) 
		return( -1 );
	if( vips_image_write( t, out ) ) {
		g_object_unref( t );
		return( -1 );
	}
	g_object_unref( t );

	return( 0 );
}
Exemple #8
0
/** 
 * vips_check_matrix: 
 * @domain: the originating domain for the error message
 * @im: image to check 
 * @out: put image as in-memory doubles here
 *
 * Matrix images must have width and height less than 1000 and have 1 band.
 *
 * Return 0 if the image will pass as a matrix, or -1 and set an error 
 * message otherwise.
 *
 * @out is set to be @im cast to double and stored in memory. Use
 * VIPS_IMAGE_ADDR() to address values in @out. @out is unreffed for you 
 * when @im is unreffed.
 *
 * See also: vips_error().
 *
 * Returns: 0 if OK, -1 otherwise.
 */
int
vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out )
{
	if( im->Xsize > 1000 || im->Ysize > 1000 ) {
		vips_error( domain, "%s", _( "matrix image too large" ) );
		return( -1 );
	}
	if( im->Bands != 1 ) {
		vips_error( domain, 
			"%s", _( "matrix image must have one band" ) ); 
		return( -1 );
	}

	if( vips_cast( im, out, VIPS_FORMAT_DOUBLE, NULL ) )
                return( -1 );
	vips_object_local( im, *out );
        if( vips_image_wio_input( *out ) )
                return( -1 );

	return( 0 );
}
Exemple #9
0
int
vips__gdal_read( const char *filename, VipsImage *out )
{
	Read *read;
	VipsImage *raw;
	VipsImage *t;

	VIPS_DEBUG_MSG( "vips__gdal_read: %s\n", 
		filename );

	raw = vips_image_new();
	vips_object_local( out, raw );

	if( !(read = read_new( filename, raw )) )
		return( -1 );

	if( vips_image_generate( raw, 
		NULL, vips__gdal_generate, NULL, read, NULL ) )
		return( -1 );

	/* Copy to out, adding a cache. Enough tiles for a complete row, plus
	 * 50%.
	 */
	if( vips_tilecache( raw, &t, 
		"tile_width", read->tile_width, 
		"tile_height", read->tile_height,
		"max_tiles", 
			(int) (1.5 * (1 + raw->Xsize / read->tile_width)),
		"threaded", FALSE,
		NULL ) ) 
		return( -1 );
	if( vips_image_write( t, out ) ) {
		g_object_unref( t );
		return( -1 );
	}
	g_object_unref( t );

	return( 0 );
}
Exemple #10
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 );
}
Exemple #11
0
/* Open an image, returning the best version of that image for thumbnailing. 
 *
 * libjpeg supports fast shrink-on-read, so if we have a JPEG, we can ask 
 * VIPS to load a lower resolution version.
 */
static VipsImage *
thumbnail_open( VipsObject *process, const char *filename )
{
	const char *loader;
	VipsImage *im;

	vips_info( "vipsthumbnail", "thumbnailing %s", filename );

	if( linear_processing )
		vips_info( "vipsthumbnail", "linear mode" ); 

	if( !(loader = vips_foreign_find_load( filename )) )
		return( NULL );

	vips_info( "vipsthumbnail", "selected loader is %s", loader ); 

	if( strcmp( loader, "VipsForeignLoadJpegFile" ) == 0 ) {
		int jpegshrink;

		/* This will just read in the header and is quick.
		 */
		if( !(im = vips_image_new_from_file( filename, NULL )) )
			return( NULL );

		jpegshrink = thumbnail_find_jpegshrink( im );

		g_object_unref( im );

		vips_info( "vipsthumbnail", 
			"loading jpeg with factor %d pre-shrink", 
			jpegshrink ); 

		/* We can't use UNBUFERRED safely on very-many-core systems.
		 */
		if( !(im = vips_image_new_from_file( filename, 
			"access", VIPS_ACCESS_SEQUENTIAL,
			"shrink", jpegshrink,
			NULL )) )
			return( NULL );
	}
	else if( strcmp( loader, "VipsForeignLoadPdfFile" ) == 0 ||
		strcmp( loader, "VipsForeignLoadSvgFile" ) == 0 ) {
		double shrink;

		/* This will just read in the header and is quick.
		 */
		if( !(im = vips_image_new_from_file( filename, NULL )) )
			return( NULL );

		shrink = calculate_shrink( im ); 

		g_object_unref( im );

		vips_info( "vipsthumbnail", 
			"loading PDF/SVG with factor %g pre-shrink", 
			shrink ); 

		/* We can't use UNBUFERRED safely on very-many-core systems.
		 */
		if( !(im = vips_image_new_from_file( filename, 
			"access", VIPS_ACCESS_SEQUENTIAL,
			"scale", 1.0 / shrink,
			NULL )) )
			return( NULL );
	}
	else if( strcmp( loader, "VipsForeignLoadWebpFile" ) == 0 ) {
		double shrink;

		/* This will just read in the header and is quick.
		 */
		if( !(im = vips_image_new_from_file( filename, NULL )) )
			return( NULL );

		shrink = calculate_shrink( im ); 

		g_object_unref( im );

		vips_info( "vipsthumbnail", 
			"loading webp with factor %g pre-shrink", 
			shrink ); 

		/* We can't use UNBUFERRED safely on very-many-core systems.
		 */
		if( !(im = vips_image_new_from_file( filename, 
			"access", VIPS_ACCESS_SEQUENTIAL,
			"shrink", (int) shrink,
			NULL )) )
			return( NULL );
	}
	else {
		/* All other formats. We can't use UNBUFERRED safely on 
		 * very-many-core systems.
		 */
		if( !(im = vips_image_new_from_file( filename, 
			"access", VIPS_ACCESS_SEQUENTIAL,
			NULL )) )
			return( NULL );
	}

	vips_object_local( process, im );

	return( im ); 
}
Exemple #12
0
/* Open an image, returning the best version of that image for thumbnailing. 
 *
 * jpegs can have embedded thumbnails ... use that if it's large enough.
 *
 * libjpeg supports fast shrink-on-read, so if we have a JPEG, we can ask 
 * VIPS to load a lower resolution version.
 */
static VipsImage *
thumbnail_open( VipsObject *process, const char *filename )
{
	const char *loader;
	VipsImage *im;

	vips_info( "vipsthumbnail", "thumbnailing %s", filename );

	if( linear_processing )
		vips_info( "vipsthumbnail", "linear mode" ); 

	if( !(loader = vips_foreign_find_load( filename )) )
		return( NULL );

	vips_info( "vipsthumbnail", "selected loader is %s", loader ); 

	if( strcmp( loader, "VipsForeignLoadJpegFile" ) == 0 ) {
		VipsImage *thumb;

		/* This will just read in the header and is quick.
		 */
		if( !(im = vips_image_new_from_file( filename )) )
			return( NULL );

		/* Try to read an embedded thumbnail. If we find one, use that
		 * instead.
		 */
		if( (thumb = thumbnail_get_thumbnail( im )) ) { 
			/* @thumb has not been fully decoded yet ... 
			 * we must not close @im
			 * until we're done with @thumb.
			 */
			vips_object_local( VIPS_OBJECT( thumb ), im );

			im = thumb;
		}
		else {
			int jpegshrink;

			vips_info( "vipsthumbnail", 
				"processing main jpeg image" );

			jpegshrink = thumbnail_find_jpegshrink( im );

			g_object_unref( im );

			vips_info( "vipsthumbnail", 
				"loading jpeg with factor %d pre-shrink", 
				jpegshrink ); 

			if( vips_foreign_load( filename, &im,
				"access", VIPS_ACCESS_SEQUENTIAL,
				"shrink", jpegshrink,
				NULL ) )
				return( NULL );
		}
	}
	else {
		/* All other formats.
		 */
		if( vips_foreign_load( filename, &im,
			"access", VIPS_ACCESS_SEQUENTIAL,
			NULL ) )
			return( NULL );
	}

	vips_object_local( process, im );

	return( im ); 
}
Exemple #13
0
static VipsFits *
vips_fits_new_write( VipsImage *in, const char *filename )
{
	VipsImage *flip;
	VipsImage *type;
	VipsFits *fits;
	int status;

	status = 0;

	if( im_check_noncomplex( "im_vips2fits", in ) ||
		im_check_uncoded( "im_vips2fits", in ) )
		return( NULL );

	/* Cast to a supported format.
	 */
	if( !(type = vips_image_new()) ||
		vips_object_local( in, type ) ||
		im_clip2fmt( in, type, vips_fits_bandfmt[in->BandFmt] ) )
		return( NULL );
	in = type;

	/* FITS has (0,0) in the bottom left, we need to flip.
	 */
	if( !(flip = vips_image_new()) ||
		vips_object_local( in, flip ) ||
		im_flipver( in, flip ) )
		return( NULL );
	in = flip;

	if( !(fits = VIPS_NEW( in, VipsFits )) )
		return( NULL );
	fits->filename = im_strdup( NULL, filename );
	fits->image = in;
	fits->fptr = NULL;
	fits->lock = NULL;
	fits->band_select = -1;
	fits->buffer = NULL;
	g_signal_connect( in, "close", 
		G_CALLBACK( vips_fits_close_cb ), fits );

	if( !(fits->filename = im_strdup( NULL, filename )) )
		return( NULL );

	/* We need to be able to hold one scanline of one band.
	 */
	if( !(fits->buffer = VIPS_ARRAY( NULL, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * in->Xsize, PEL )) )
		return( NULL );

	/* fits_create_file() will fail if there's a file of thet name, unless
	 * we put a "!" in front ofthe filename. This breaks conventions with
	 * the rest of vips, so just unlink explicitly.
	 */
	g_unlink( filename );

	if( fits_create_file( &fits->fptr, filename, &status ) ) {
		im_error( "fits", _( "unable to write to \"%s\"" ), filename );
		vips_fits_error( status );
		return( NULL );
	}

	fits->lock = g_mutex_new();

	return( fits );
}