Esempio n. 1
0
static void *
vips_fits_write_meta( VipsImage *image, 
	const char *field, GValue *value, void *a )
{
	VipsFits *fits = (VipsFits *) a;

	int status;
	const char *value_str;

	status = 0;

	/* We want fields which start "fits-".
	 */
	if( !vips_isprefix( "fits-", field ) )
		return( NULL );

	/* The value should be a refstring, since we wrote it in fits2vips 
	 * above ^^.
	 */
	value_str = vips_value_get_ref_string( value, NULL );

	VIPS_DEBUG_MSG( "vips_fits_write_meta: setting meta on fits image:\n" );
	VIPS_DEBUG_MSG( " value == \"%s\"\n", value_str );

	if( fits_write_record( fits->fptr, value_str, &status ) ) {
		vips_fits_error( status );
		return( a );
	}

	return( NULL );
}
Esempio n. 2
0
static void
vips_exif_set_int( ExifData *ed, 
	ExifEntry *entry, unsigned long component, void *data )
{
	int value = *((int *) data);

	ExifByteOrder bo;
	size_t sizeof_component;
	size_t offset = component;

	if( entry->components <= component ) {
		VIPS_DEBUG_MSG( "vips_exif_set_int: too few components\n" );
		return;
	}

	/* Wait until after the component check to make sure we cant get /0.
	 */
	bo = exif_data_get_byte_order( ed );
	sizeof_component = entry->size / entry->components;
	offset = component * sizeof_component;

	VIPS_DEBUG_MSG( "vips_exif_set_int: %s = %d\n",
		vips_exif_entry_get_name( entry ), value );

	if( entry->format == EXIF_FORMAT_SHORT ) 
		exif_set_short( entry->data + offset, bo, value );
	else if( entry->format == EXIF_FORMAT_SSHORT ) 
		exif_set_sshort( entry->data + offset, bo, value );
	else if( entry->format == EXIF_FORMAT_LONG ) 
		exif_set_long( entry->data + offset, bo, value );
	else if( entry->format == EXIF_FORMAT_SLONG ) 
		exif_set_slong( entry->data + offset, bo, value );
}
Esempio n. 3
0
/* Renumber after clustering. We will have removed a lot of hlines ... shuffle
 * the rest down, adjust all the vline references.
 */
static void
boxes_renumber( Boxes *boxes )
{
	int i, j;

	VIPS_DEBUG_MSG( "boxes_renumber: renumbering ...\n" );

	/* Loop for all zero-weight hlines.
	 */
	for( i = 0; i < boxes->n_hline; ) {
		if( boxes->hline[i].weight > 0 ) {
			i++;
			continue;
		}

		/* We move hlines i + 1 down, so we need to adjust all
		 * band[] refs to match.
		 */
		for( j = 0; j < boxes->n_velement; j++ )
			if( boxes->velement[j].band > i ) 
				boxes->velement[j].band -= 1;

		memmove( boxes->hline + i, boxes->hline + i + 1, 
			sizeof( HLine ) * (boxes->n_hline - i - 1) );
		boxes->n_hline -= 1;
	}

	VIPS_DEBUG_MSG( "boxes_renumber: ... %d hlines remain\n", 
		boxes->n_hline );
}
Esempio n. 4
0
/* Does both signed and unsigned rationals from a double*.
 *
 * Don't change the exit entry if the value currently there is a good
 * approximation of the double we are trying to set.
 */
static void
vips_exif_set_double( ExifData *ed, 
	ExifEntry *entry, unsigned long component, void *data )
{
	double value = *((double *) data);

	ExifByteOrder bo;
	size_t sizeof_component;
	size_t offset;
	double old_value;

	if( entry->components <= component ) {
		VIPS_DEBUG_MSG( "vips_exif_set_double: "
			"too few components\n" );
		return;
	}

	/* Wait until after the component check to make sure we cant get /0.
	 */
	bo = exif_data_get_byte_order( ed );
	sizeof_component = entry->size / entry->components;
	offset = component * sizeof_component;

	VIPS_DEBUG_MSG( "vips_exif_set_double: %s = %g\n",
		vips_exif_entry_get_name( entry ), value );

	if( entry->format == EXIF_FORMAT_RATIONAL ) {
		ExifRational rv;

		rv = exif_get_rational( entry->data + offset, bo );
		old_value = (double) rv.numerator / rv.denominator;
		if( VIPS_FABS( old_value - value ) > 0.0001 ) {
			vips_exif_double_to_rational( value, &rv ); 

			VIPS_DEBUG_MSG( "vips_exif_set_double: %u / %u\n", 
				rv.numerator, 
				rv.denominator ); 

			exif_set_rational( entry->data + offset, bo, rv );
		}
	}
	else if( entry->format == EXIF_FORMAT_SRATIONAL ) {
		ExifSRational srv;

		srv = exif_get_srational( entry->data + offset, bo );
		old_value = (double) srv.numerator / srv.denominator;
		if( VIPS_FABS( old_value - value ) > 0.0001 ) {
			vips_exif_double_to_srational( value, &srv ); 

			VIPS_DEBUG_MSG( "vips_exif_set_double: %d / %d\n", 
				srv.numerator, srv.denominator ); 

			exif_set_srational( entry->data + offset, bo, srv );
		}
	}
}
Esempio n. 5
0
/* Find existing tile, make a new tile, or if we have a full set of tiles, 
 * reuse one.
 */
static VipsTile *
vips_tile_find( VipsBlockCache *cache, int x, int y )
{
	VipsTile *tile;
	VipsTileSearch search;

	/* In cache already?
	 */
	if( (tile = vips_tile_search( cache, x, y )) ) {
		VIPS_DEBUG_MSG( "vips_tile_find: tile %d x %d in cache\n", 
			x, y ); 
		return( tile );
	}

	/* VipsBlockCache not full?
	 */
	if( cache->max_tiles == -1 ||
		cache->ntiles < cache->max_tiles ) {
		VIPS_DEBUG_MSG( "vips_tile_find: making new tile at %d x %d\n", 
			x, y ); 
		if( !(tile = vips_tile_new( cache, x, y )) )
			return( NULL );

		return( tile );
	}

	/* Reuse an old one.
	 */
	search.oldest = cache->time;
	search.topmost = cache->in->Ysize;
	search.tile = NULL;
	g_hash_table_foreach( cache->tiles, vips_tile_search_recycle, &search );
	tile = search.tile; 

	if( !tile ) {
		/* There are no tiles we can reuse -- we have to make another
		 * for now. They will get culled down again next time around.
		 */
		if( !(tile = vips_tile_new( cache, x, y )) ) 
			return( NULL );

		return( tile );
	}

	VIPS_DEBUG_MSG( "tilecache: reusing tile %d x %d\n", 
		tile->pos.left, tile->pos.top );

	if( vips_tile_move( tile, x, y ) )
		return( NULL );

	return( tile );
}
Esempio n. 6
0
int
vips__openslide_isslide( const char *filename )
{
#ifdef HAVE_OPENSLIDE_3_4
	const char *vendor;
	int ok;

	vendor = openslide_detect_vendor( filename );

	/* Generic tiled tiff images can be opened by openslide as well.
	 * Only offer to load this file if it's not a generic tiff since
	 * we want vips_tiffload() to handle these.
	 */
	ok = ( vendor &&
		strcmp( vendor, "generic-tiff" ) != 0 );

	VIPS_DEBUG_MSG( "vips__openslide_isslide: %s - %d\n", filename, ok );

	return( ok );
#else
	openslide_t *osr;
	int ok;

	ok = 0;
	osr = openslide_open( filename );

	if( osr ) {
		const char *vendor;

		/* Generic tiled tiff images can be opened by openslide as
		 * well. Only offer to load this file if it's not a generic
		 * tiff since we want vips_tiffload() to handle these.
		 */
		vendor = openslide_get_property_value( osr,
			OPENSLIDE_PROPERTY_NAME_VENDOR );

		/* vendor will be NULL if osr is in error state.
		 */
		if( vendor &&
			strcmp( vendor, "generic-tiff" ) != 0 )
			ok = 1;

		openslide_close( osr );
	} 

	VIPS_DEBUG_MSG( "vips__openslide_isslide: %s - %d\n", filename, ok );

	return( ok );
#endif
}
Esempio n. 7
0
static int
vips_statistic_scan( VipsRegion *region, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsStatistic *statistic = VIPS_STATISTIC( a );
	VipsStatisticClass *class = VIPS_STATISTIC_GET_CLASS( statistic );

	VipsRect *r = &region->valid;
	int lsk = IM_REGION_LSKIP( region );

	int y;
	PEL *p;

	VIPS_DEBUG_MSG( "vips_statistic_scan: %d x %d @ %d x %d\n",
		r->width, r->height, r->left, r->top );

	p = (PEL *) IM_REGION_ADDR( region, r->left, r->top ); 
	for( y = 0; y < r->height; y++ ) { 
		if( class->scan( statistic, 
			seq, r->left, r->top + y, p, r->width ) ) 
			return( -1 );
		p += lsk;
	} 

	/* If we've requested stop, pass the message on.
	 */
	if( statistic->stop )
		*stop = TRUE;

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

	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_image_copy_fields( conversion->out, sequential->in ) )
		return( -1 );
        vips_demand_hint( conversion->out, 
		VIPS_DEMAND_STYLE_FATSTRIP, sequential->in, NULL );

	if( vips_image_generate( conversion->out,
		vips_start_one, vips_sequential_generate, vips_stop_one, 
		sequential->in, sequential ) )
		return( -1 );

	return( 0 );
}
Esempio n. 9
0
static void
vips_operation_finalize( GObject *gobject )
{
	VIPS_DEBUG_MSG( "vips_operation_finalize: %p\n", gobject );

	G_OBJECT_CLASS( vips_operation_parent_class )->finalize( gobject );
}
Esempio n. 10
0
int
vips__openslide_isslide( const char *filename )
{
	openslide_t *osr;
	const char *vendor;
	int ok;

	ok = 0;
	if( (osr = openslide_open( filename )) ) {
		/* Generic tiled tiff images can be opened by openslide as
		 * well. Only offer to load this file if it's not a generic
		 * tiff since we want vips_tiffload() to handle these.
		 */
		vendor = openslide_get_property_value( osr,
			OPENSLIDE_PROPERTY_NAME_VENDOR );
		if( vendor &&
			strcmp( vendor, "generic-tiff" ) != 0 )
			ok = 1;
		openslide_close( osr );
	} 

	VIPS_DEBUG_MSG( "vips__openslide_isslide: %s - %d\n", filename, ok );

	return( ok );
}
Esempio n. 11
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 );
}
Esempio n. 12
0
static int
vips_tile_cache_build( VipsObject *object )
{
	VipsConversion *conversion = VIPS_CONVERSION( object );
	VipsTileCache *cache = (VipsTileCache *) object;

	VIPS_DEBUG_MSG( "vips_tile_cache_build\n" );

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

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

	if( vips_image_copy_fields( conversion->out, cache->in ) )
		return( -1 );
        vips_demand_hint( conversion->out, 
		VIPS_DEMAND_STYLE_SMALLTILE, cache->in, NULL );

	if( vips_image_generate( conversion->out,
		vips_start_one, vips_tile_cache_gen, vips_stop_one, 
		cache->in, cache ) )
		return( -1 );

	return( 0 );
}
Esempio n. 13
0
static void
vips_thread_profile_save( VipsThreadProfile *profile )
{
	g_mutex_lock( vips__global_lock );

	VIPS_DEBUG_MSG( "vips_thread_profile_save: %s\n", profile->name ); 

	if( !vips__thread_fp ) { 
		vips__thread_fp = 
			vips__file_open_write( "vips-profile.txt", TRUE );
		if( !vips__thread_fp ) {
			g_mutex_unlock( vips__global_lock );
			g_warning( "unable to create profile log" ); 
			return;
		}

		printf( "recording profile in vips-profile.txt\n" );  
	}

	fprintf( vips__thread_fp, "thread: %s (%p)\n", profile->name, profile );
	g_hash_table_foreach( profile->gates, 
		vips_thread_profile_save_cb, vips__thread_fp );
	vips_thread_profile_save_gate( profile->memory, vips__thread_fp ); 

	g_mutex_unlock( vips__global_lock );
}
Esempio n. 14
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 );
}
Esempio n. 15
0
static void
vips_exif_update( ExifData *ed, VipsImage *image )
{
	VipsExifRemove ve;

	VIPS_DEBUG_MSG( "vips_exif_update: \n" );

	/* If this exif came from the image (rather than being an exif block we
	 * have made afresh), then any fields which are in the block but not on
	 * the image must have been deliberately removed. Remove them from the
	 * block as well.
	 *
	 * If there are any string-valued fields (eg. comment etc.) which
	 * exist as libvips metadata tags, we must also remove those from the
	 * exif block.
	 *
	 * libexif does not allow you to change string lengths, you must make
	 * new tags, so we have to remove ready to re-add.
	 */
	if( vips_image_get_typeof( image, VIPS_META_EXIF_NAME ) ) {
		ve.image = image;
		ve.ed = ed;
		exif_data_foreach_content( ed, 
			(ExifDataForeachContentFunc) vips_exif_exif_content, 
			&ve );
	}

	/* Walk the image and add any exif- that's set in image metadata.
	 */
	vips_image_map( image, vips_exif_image_field, ed );
}
Esempio n. 16
0
static int
vips_region_build( VipsObject *object )
{
	VipsRegion *region = VIPS_REGION( object );
	VipsImage *image = region->im;

	VIPS_DEBUG_MSG( "vips_region_build: %p\n", region );

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

	vips__region_take_ownership( region );

	/* We're usually inside the ss lock anyway. But be safe ...
	 */
	VIPS_GATE_START( "vips_region_build: wait" );

	g_mutex_lock( image->sslock );

	VIPS_GATE_STOP( "vips_region_build: wait" );

	image->regions = g_slist_prepend( image->regions, region );

	g_mutex_unlock( image->sslock );

	return( 0 );
}
Esempio n. 17
0
/* Does both signed and unsigned rationals from a char *.
 */
static void
vips_exif_set_rational( ExifData *ed, 
	ExifEntry *entry, unsigned long component, void *data )
{
	char *value = (char *) data;

	ExifByteOrder bo;
	size_t sizeof_component;
	size_t offset;

	if( entry->components <= component ) {
		VIPS_DEBUG_MSG( "vips_exif_set_rational: "
			"too few components\n" );
		return;
	}

	/* Wait until after the component check to make sure we cant get /0.
	 */
	bo = exif_data_get_byte_order( ed );
	sizeof_component = entry->size / entry->components;
	offset = component * sizeof_component;

	VIPS_DEBUG_MSG( "vips_exif_set_rational: %s = \"%s\"\n",
		vips_exif_entry_get_name( entry ), value );

	if( entry->format == EXIF_FORMAT_RATIONAL ) {
		ExifRational rv;

		vips_exif_parse_rational( value, &rv ); 

		VIPS_DEBUG_MSG( "vips_exif_set_rational: %u / %u\n", 
			rv.numerator, 
			rv.denominator ); 

		exif_set_rational( entry->data + offset, bo, rv );
	}
	else if( entry->format == EXIF_FORMAT_SRATIONAL ) {
		ExifSRational srv;

		vips_exif_parse_srational( value, &srv ); 

		VIPS_DEBUG_MSG( "vips_exif_set_rational: %d / %d\n", 
			srv.numerator, srv.denominator ); 

		exif_set_srational( entry->data + offset, bo, srv );
	}
}
Esempio n. 18
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 );
}
Esempio n. 19
0
static void
vips_region_finalize( GObject *gobject )
{
#ifdef VIPS_DEBUG
	VIPS_DEBUG_MSG( "vips_region_finalize: " );
	vips_object_print_name( VIPS_OBJECT( gobject ) );
	VIPS_DEBUG_MSG( "\n" );
#endif /*VIPS_DEBUG*/

#ifdef VIPS_DEBUG
	g_mutex_lock( vips__global_lock );
	vips__regions_all = g_slist_remove( vips__regions_all, gobject ); 
	g_mutex_unlock( vips__global_lock );
#endif /*VIPS_DEBUG*/

	G_OBJECT_CLASS( vips_region_parent_class )->finalize( gobject );
}
Esempio n. 20
0
static int
vips_fits_write( VipsRegion *region, VipsRect *area, void *a )
{
	VipsFits *fits = (VipsFits *) a;
	VipsImage *image = fits->image;
	int es = VIPS_IMAGE_SIZEOF_ELEMENT( image );
	int ps = VIPS_IMAGE_SIZEOF_PEL( image );

	int status;
	int y, b, x, k;

	status = 0;

	VIPS_DEBUG_MSG( "vips_fits_write: "
		"writing left = %d, top = %d, width = %d, height = %d\n", 
		area->left, area->top, area->width, area->height );

	/* We need to write a band at a time. We can't bandsplit in vips,
	 * since vips_sink_disc() can't loop over many images at once, sadly.
	 */

	for( y = 0; y < area->height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( region, 
			area->left, area->top + y );

		for( b = 0; b < image->Bands; b++ ) {
			VipsPel *p1, *q;
			long fpixel[3];

			p1 = p + b * es;
			q = fits->buffer;

			for( x = 0; x < area->width; x++ ) {
				for( k = 0; k < es; k++ ) 
					q[k] = p1[k];
				
				q += es;
				p1 += ps;
			}

			fpixel[0] = area->left + 1;
			fpixel[1] = area->top + y + 1;
			fpixel[2] = b + 1;

			/* No need to lock, write functions are single-threaded.
			 */

			if( fits_write_pix( fits->fptr, fits->datatype, 
				fpixel, area->width, fits->buffer, 
				&status ) ) {
				vips_fits_error( status );
				return( -1 );
			}
		}
	}

	return( 0 );
}
Esempio n. 21
0
static void
vips_thread_profile_free( VipsThreadProfile *profile )
{
	VIPS_DEBUG_MSG( "vips_thread_profile_free: %s\n", profile->name ); 

	VIPS_FREEF( g_hash_table_destroy, profile->gates );
	VIPS_FREEF( vips_thread_gate_free, profile->memory );
	VIPS_FREE( profile );
}
Esempio n. 22
0
static int
vips_fits_set_header( VipsFits *fits, VipsImage *in )
{
	int status;
	int bitpix;
	int i;

	status = 0;

	fits->naxis = 3;
	fits->naxes[0] = in->Xsize;
	fits->naxes[1] = in->Ysize;
	fits->naxes[2] = in->Bands;

	for( i = 0; i < VIPS_NUMBER( fits2vips_formats ); i++ )
		if( fits2vips_formats[i][1] == in->BandFmt )
			break;
	if( i == VIPS_NUMBER( fits2vips_formats ) ) {
		vips_error( "fits", 
			_( "unsupported BandFmt %d\n" ), in->BandFmt );
		return( -1 );
	}
	bitpix = fits2vips_formats[i][0];
	fits->datatype = fits2vips_formats[i][2];

#ifdef VIPS_DEBUG
	VIPS_DEBUG_MSG( "naxis = %d\n", fits->naxis );
	for( i = 0; i < fits->naxis; i++ )
		VIPS_DEBUG_MSG( "%d) %lld\n", i, fits->naxes[i] );
	VIPS_DEBUG_MSG( "bitpix = %d\n", bitpix );
#endif /*VIPS_DEBUG*/

	if( fits_create_imgll( fits->fptr, bitpix, fits->naxis, 
		fits->naxes, &status ) ) {
		vips_fits_error( status );
		return( -1 );
	}

	if( vips_image_map( in,
		(VipsImageMapFn) vips_fits_write_meta, fits ) )
		return( -1 );

	return( 0 );
}
Esempio n. 23
0
/* Set the EXIF resolution from the vips xres/yres tags.
 */
static int
vips_exif_resolution_from_image( ExifData *ed, VipsImage *image )
{
	double xres, yres;
	const char *p;
	int unit;

	VIPS_DEBUG_MSG( "vips_exif_resolution_from_image: vips res of %g, %g\n",
		image->Xres, image->Yres );

	/* Default to inches, more progs support it.
	 */
	unit = 2;
	if( vips_image_get_typeof( image, VIPS_META_RESOLUTION_UNIT ) &&
		!vips_image_get_string( image, 
			VIPS_META_RESOLUTION_UNIT, &p ) ) {
		if( vips_isprefix( "cm", p ) ) 
			unit = 3;
		else if( vips_isprefix( "none", p ) ) 
			unit = 1;
	}

	switch( unit ) {
	case 1:
		xres = image->Xres;
		yres = image->Yres;
		break;

	case 2:
		xres = image->Xres * 25.4;
		yres = image->Yres * 25.4;
		break;

	case 3:
		xres = image->Xres * 10.0;
		yres = image->Yres * 10.0;
		break;

	default:
		g_warning( "%s", _( "unknown EXIF resolution unit" ) );
		return( 0 );
	}

	/* Main image xres/yres/unit are in ifd0. ifd1 has the thumbnail
	 * xres/yres/unit.
	 */
	vips_exif_set_tag( ed, 0, EXIF_TAG_X_RESOLUTION, 
		vips_exif_set_double, (void *) &xres );
	vips_exif_set_tag( ed, 0, EXIF_TAG_Y_RESOLUTION, 
		vips_exif_set_double, (void *) &yres );
	vips_exif_set_tag( ed, 0, EXIF_TAG_RESOLUTION_UNIT, 
		vips_exif_set_int, (void *) &unit );

	return( 0 );
}
Esempio n. 24
0
void 
VImage::call_option_string( const char *operation_name, 
	const char *option_string, VOption *options ) 
	throw( VError )
{
	VipsOperation *operation;

	VIPS_DEBUG_MSG( "vips_call_by_name: starting for %s ...\n", 
		operation_name );

	if( !(operation = vips_operation_new( operation_name )) ) {
		if( options )
			delete options;
		throw( VError() ); 
	}

	/* Set str options before vargs options, so the user can't 
	 * override things we set deliberately.
	 */
	if( option_string &&
		vips_object_set_from_string( VIPS_OBJECT( operation ), 
			option_string ) ) {
		vips_object_unref_outputs( VIPS_OBJECT( operation ) );
		g_object_unref( operation ); 
		delete options; 
		throw( VError() ); 
	}

	if( options )
		options->set_operation( operation );

	/* Build from cache.
	 */
	if( vips_cache_operation_buildp( &operation ) ) {
		vips_object_unref_outputs( VIPS_OBJECT( operation ) );
		delete options; 
		throw( VError() ); 
	}

	/* Walk args again, writing output.
	 */
	if( options )
		options->get_operation( operation );

	/* We're done with options!
	 */
	delete options; 

	/* The operation we have built should now have been reffed by 
	 * one of its arguments or have finished its work. Either 
	 * way, we can unref.
	 */
	g_object_unref( operation );
}
Esempio n. 25
0
/**
 * vips_verror: 
 * @domain: the source of the error
 * @fmt: printf()-style format string for the error
 * @ap: arguments to the format string
 *
 * Append a message to the error buffer.
 *
 * See also: vips_error().
 */
void 
vips_verror( const char *domain, const char *fmt, va_list ap )
{
	g_mutex_lock( vips__global_lock );
	vips_buf_appendf( &vips_error_buf, "%s: ", domain );
	vips_buf_vappendf( &vips_error_buf, fmt, ap );
	vips_buf_appends( &vips_error_buf, "\n" );
	g_mutex_unlock( vips__global_lock );

	VIPS_DEBUG_MSG( "vips_verror: %s\n", fmt );
}
Esempio n. 26
0
static void
vips_region_dispose( GObject *gobject )
{
	VipsRegion *region = VIPS_REGION( gobject );
	VipsImage *image = region->im;

#ifdef VIPS_DEBUG
	VIPS_DEBUG_MSG( "vips_region_dispose: " );
	vips_object_print_name( VIPS_OBJECT( gobject ) );
	VIPS_DEBUG_MSG( "\n" );
#endif /*VIPS_DEBUG*/

	vips_object_preclose( VIPS_OBJECT( gobject ) );

        /* Stop this sequence.
         */
        vips__region_stop( region );

	/* Free any attached memory.
	 */
	VIPS_FREEF( vips_window_unref, region->window );
	VIPS_FREEF( vips_buffer_unref, region->buffer );

	/* Detach from image. 
	 */
	VIPS_GATE_START( "vips_region_dispose: wait" );

	g_mutex_lock( image->sslock );

	VIPS_GATE_STOP( "vips_region_dispose: wait" );

	image->regions = g_slist_remove( image->regions, region );

	g_mutex_unlock( image->sslock );

	region->im = NULL;

	g_object_unref( image );

	G_OBJECT_CLASS( vips_region_parent_class )->dispose( gobject );
}
Esempio n. 27
0
/* Generate func.
 */
static int
vips_tile_cache_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsRegion *in = (VipsRegion *) seq;
	VipsTileCache *cache = (VipsTileCache *) b;
	const int tw = cache->tile_width;
	const int th = cache->tile_height;
	VipsRect *r = &or->valid;

	/* Find top left of tiles we need.
	 */
	int xs = (r->left / tw) * tw;
	int ys = (r->top / th) * th;

	int x, y;

	g_mutex_lock( cache->lock );

	VIPS_DEBUG_MSG( "vips_tile_cache_gen: "
		"left = %d, top = %d, width = %d, height = %d\n",
		r->left, r->top, r->width, r->height );

	for( y = ys; y < VIPS_RECT_BOTTOM( r ); y += th )
		for( x = xs; x < VIPS_RECT_RIGHT( r ); x += tw ) {
			Tile *tile;
			VipsRect tarea;
			VipsRect hit;

			if( !(tile = tile_find( cache, in, x, y )) ) {
				g_mutex_unlock( cache->lock );
				return( -1 );
			}

			/* The area of the tile.
			 */
			tarea.left = x;
			tarea.top = y;
			tarea.width = tw;
			tarea.height = th;

			/* The part of the tile that we need.
			 */
			vips_rect_intersectrect( &tarea, r, &hit );

			copy_region( tile->region, or, &hit );
		}

	g_mutex_unlock( cache->lock );

	return( 0 );
}
Esempio n. 28
0
int
vips__fits_read( const char *filename, VipsImage *out )
{
	VipsImage *t;
	int n_bands;

	VIPS_DEBUG_MSG( "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.
	 */

	t = vips_image_new();
	if( vips__fits_read_header( filename, t ) ) {
		g_object_unref( t );
		return( -1 );
	}
	n_bands = t->Bands;
	g_object_unref( t );

	if( n_bands == 1 ) {
		if( fits2vips( filename, out, 0 ) )
			return( -1 );
	}
	else {
		VipsImage **x;
		int i;

		t = vips_image_new();
		x = (VipsImage **) vips_object_local_array( VIPS_OBJECT( t ), 
			n_bands + 1 );

		for( i = 0; i < n_bands; i++ ) {
			x[i] = vips_image_new();
			if( fits2vips( filename, x[i], i ) ) {
				g_object_unref( t );
				return( -1 );
			}
		}

		if( vips_bandjoin( x, &x[n_bands], n_bands, NULL ) ||
			vips_image_write( x[n_bands], out ) ) {
			g_object_unref( t );
			return( -1 );
		}

		g_object_unref( t );
	}

	return( 0 );
}
Esempio n. 29
0
int
vips__fits_isfits( const char *filename )
{
	fitsfile *fptr;
	int status;

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

	status = 0;

	if( fits_open_image( &fptr, filename, READONLY, &status ) ) {
		VIPS_DEBUG_MSG( "isfits: error reading \"%s\"\n", filename );
#ifdef VIPS_DEBUG
		vips_fits_error( status );
#endif /*VIPS_DEBUG*/

		return( 0 );
	}
	fits_close_file( fptr, &status );

	return( 1 );
}
Esempio n. 30
0
/* Exif also tracks image dimensions. 
 */
static int
vips_exif_set_dimensions( ExifData *ed, VipsImage *im )
{
	VIPS_DEBUG_MSG( "vips_exif_set_dimensions: vips size of %d, %d\n",
		im->Xsize, im->Ysize );

	vips_exif_set_tag( ed, 2, EXIF_TAG_PIXEL_X_DIMENSION, 
		vips_exif_set_int, (void *) &im->Xsize );
	vips_exif_set_tag( ed, 2, EXIF_TAG_PIXEL_Y_DIMENSION, 
		vips_exif_set_int, (void *) &im->Ysize );

	return( 0 );
}