예제 #1
0
/**
 * vips_cache_operation_add:
 * @operation: (transfer none): pointer to operation to add
 *
 * Add a built operation to the cache. The cache will ref the operation. 
 */
void
vips_cache_operation_add( VipsOperation *operation )
{
	g_assert( VIPS_OBJECT( operation )->constructed ); 

	g_mutex_lock( vips_cache_lock );

	/* If two threads call the same operation at the same time, 
	 * we can get multiple adds. Let the first one win. See
	 * https://github.com/jcupitt/libvips/pull/181
	 */
	if( !g_hash_table_lookup( vips_cache_table, operation ) ) {
		VipsOperationFlags flags = 
			vips_operation_get_flags( operation );
		gboolean nocache = flags & VIPS_OPERATION_NOCACHE;

		/* Has to be after _build() so we can see output args.
		 */
		if( vips__cache_trace ) {
			if( nocache )
				printf( "vips cache : " );
			else
				printf( "vips cache+: " );
			vips_object_print_summary( VIPS_OBJECT( operation ) );
		}

		if( !nocache ) 
			vips_cache_insert( operation );
	}

	g_mutex_unlock( vips_cache_lock );

	vips_cache_trim();
}
예제 #2
0
/**
 * vips_cache_operation_lookup:
 * @operation: (transfer none): pointer to operation to lookup
 *
 * Look up an unbuilt @operation in the cache. If we get a hit, ref and 
 * return the old operation. If there's no hit, return NULL.
 *
 * Returns: (transfer full): the cache hit, if any.
 */
VipsOperation *
vips_cache_operation_lookup( VipsOperation *operation )
{
	VipsOperationCacheEntry *hit;
	VipsOperation *result;

	g_assert( VIPS_IS_OPERATION( operation ) );
	g_assert( !VIPS_OBJECT( operation )->constructed ); 

#ifdef VIPS_DEBUG
	printf( "vips_cache_operation_lookup: " );
	vips_object_print_dump( VIPS_OBJECT( operation ) );
#endif /*VIPS_DEBUG*/

	g_mutex_lock( vips_cache_lock );

	result = NULL;

	if( (hit = g_hash_table_lookup( vips_cache_table, operation )) ) {
		if( vips__cache_trace ) {
			printf( "vips cache*: " );
			vips_object_print_summary( VIPS_OBJECT( operation ) );
		}

		result = hit->operation;
		vips_cache_ref( result );
	}

	g_mutex_unlock( vips_cache_lock );

	return( result );
}
예제 #3
0
/**
 * vips_cache_operation_buildp: (skip)
 * @operation: pointer to operation to lookup
 *
 * Look up @operation in the cache. If we get a hit, unref @operation, ref the
 * old one and return that through the argument pointer. 
 *
 * If we miss, build and add @operation.
 *
 * Returns: 0 on success, or -1 on error.
 */
int
vips_cache_operation_buildp( VipsOperation **operation )
{
	VipsOperation *hit;

	g_assert( VIPS_IS_OPERATION( *operation ) );

#ifdef VIPS_DEBUG
	printf( "vips_cache_operation_buildp: " );
	vips_object_print_dump( VIPS_OBJECT( *operation ) );
#endif /*VIPS_DEBUG*/

	if( (hit = vips_cache_operation_lookup( *operation )) ) {
		g_object_unref( *operation );
		*operation = hit;
	}
	else {
		if( vips_object_build( VIPS_OBJECT( *operation ) ) ) 
			return( -1 );

		vips_cache_operation_add( *operation ); 
	}

	return( 0 );
}
예제 #4
0
파일: VImage.cpp 프로젝트: songfj/libvips
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 );
}
예제 #5
0
static Layer *
pyramid_new( Write *write, Layer *above, int width, int height )
{
	Layer *layer;

	layer = VIPS_NEW( write->im, Layer );
	layer->write = write;
	layer->width = width;
	layer->height = height; 

	if( !above )
		/* Top of pyramid.
		 */
		layer->sub = 1;	
	else
		layer->sub = above->sub * 2;

	layer->lname = NULL;
	layer->tif = NULL;
	layer->image = NULL;
	layer->write_y = 0;
	layer->y = 0;
	layer->strip = NULL;
	layer->copy = NULL;

	layer->below = NULL;
	layer->above = above;

	if( write->pyramid )
		if( layer->width > write->tilew || 
			layer->height > write->tileh ) 
			layer->below = pyramid_new( write, layer, 
				width / 2, height / 2 );

	/* The name for the top layer is the output filename.
	 *
	 * We need lname to be freed automatically: it has to stay 
	 * alive until after write_gather().
	 */
	if( !above ) 
		layer->lname = vips_strdup( VIPS_OBJECT( write->im ), 
			write->filename );
	else {
		char *lname;

		lname = vips__temp_name( "%s.tif" );
		layer->lname = vips_strdup( VIPS_OBJECT( write->im ), lname );
		g_free( lname );
	}

	return( layer );
}
예제 #6
0
static Read *
read_new_filename( VipsImage *out, const char *name, gboolean readbehind )
{
	Read *read;

	if( !(read = read_new( out, readbehind )) )
		return( NULL );

	read->name = vips_strdup( VIPS_OBJECT( out ), name );

        if( !(read->fp = vips__file_open_read( name, NULL, FALSE )) ) 
		return( NULL );

	/* Catch PNG errors from png_read_info().
	 */
	if( setjmp( png_jmpbuf( read->pPng ) ) ) 
		return( NULL );

	/* Read enough of the file that png_get_interlace_type() will start
	 * working.
	 */
	png_init_io( read->pPng, read->fp );
	png_read_info( read->pPng, read->pInfo );

	return( read );
}
예제 #7
0
파일: webp2vips.c 프로젝트: gargsms/libvips
static int
read_image( Read *read, VipsImage *out )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );

	t[0] = vips_image_new_memory();
	if( read_header( read, t[0] ) )
		return( -1 );
	if( vips_image_write_prepare( t[0] ) ) 
		return( -1 );

	read->config.output.u.RGBA.rgba = VIPS_IMAGE_ADDR( t[0], 0, 0 );
	read->config.output.u.RGBA.stride = VIPS_IMAGE_SIZEOF_LINE( t[0] );
	read->config.output.u.RGBA.size = VIPS_IMAGE_SIZEOF_IMAGE( t[0] );
	read->config.output.is_external_memory = 1;

	if( WebPDecode( (uint8_t *) read->data, read->length, 
		&read->config) != VP8_STATUS_OK ) {
		vips_error( "webp2vips", "%s", _( "unable to read pixels" ) ); 
		return( -1 );
	}

	if( vips_image_write( t[0], out ) )
		return( -1 );

	return( 0 );
}
예제 #8
0
파일: ppm.c 프로젝트: FlavioFalcao/libvips
/* Read a ppm/pgm file using mmap().
 */
static int
read_mmap( FILE *fp, const char *filename, int msb_first, VipsImage *out )
{
	const guint64 header_offset = ftell( fp );
	VipsImage *x = vips_image_new();
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( x ), 3 );

	if( vips_rawload( filename, &t[0], 
			out->Xsize, out->Ysize, VIPS_IMAGE_SIZEOF_PEL( out ), 
			"offset", header_offset,
			NULL ) ||
		vips_copy( t[0], &t[1],
			"bands", out->Bands, 
			"format", out->BandFmt, 
			"coding", out->Coding, 
			NULL ) ||
		vips_copy( t[1], &t[2], 
			"swap", !vips_amiMSBfirst(), 
			NULL ) ||
		vips_image_write( t[2], out ) ) {
		g_object_unref( x );
		return( -1 );
	}
	g_object_unref( x );

	return( 0 );
}
예제 #9
0
static void
vips_cache_unref( VipsOperation *operation )
{
	(void) vips_argument_map( VIPS_OBJECT( operation ),
		vips_object_unref_arg, NULL, NULL );
	g_object_unref( operation );
}
예제 #10
0
파일: vipsobject.c 프로젝트: jcupitt/nip2
/* Make a vo and supply args from nip2.
 */
static gboolean
vo_args( Vo *vo, PElement *required, PElement *optional )
{
	/* Gather supplied required input args list.
	 */
	if( heap_map_list( required, 
		(heap_map_list_fn) vo_gather_required, vo, NULL ) ) 
		return( FALSE );

	/* Set required input arguments.
	 */
	if( vips_argument_map( VIPS_OBJECT( vo->object ),
		(VipsArgumentMapFn) vo_set_required_input, vo, NULL ) ) 
		return( FALSE );
	if( vo->nargs_supplied != vo->nargs_required ) {
		error_top( _( "Wrong number of required arguments." ) );
		error_sub( _( "Operation \"%s\" has %d required arguments, "
			"you supplied %d." ),
			vo->name,
			vo->nargs_required,
			vo->nargs_supplied );
		return( FALSE );
	}

	/* Set all optional input args.
	 */
	if( !vo_set_optional( vo, optional ) ) 
		return( FALSE );

	return( TRUE );
}
예제 #11
0
파일: webp2vips.c 프로젝트: allsmy/libvips
static int
read_image( Read *read, VipsImage *out )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );
	webp_decoder decoder;

	t[0] = vips_image_new_memory();
	if( read_header( read, t[0] ) )
		return( -1 );
	if( vips_image_write_prepare( t[0] ) ) 
		return( -1 );

	if( t[0]->Bands == 3 )
		decoder = WebPDecodeRGBInto;
	else
		decoder = WebPDecodeRGBAInto;

	if( !decoder( (uint8_t *) read->data, read->length, 
		VIPS_IMAGE_ADDR( t[0], 0, 0 ), 
		VIPS_IMAGE_SIZEOF_IMAGE( t[0] ),
		VIPS_IMAGE_SIZEOF_LINE( t[0] ) ) ) { 
		vips_error( "webp2vips", "%s", _( "unable to read pixels" ) ); 
		return( -1 );
	}

	if( vips_image_write( t[0], out ) )
		return( -1 );

	return( 0 );
}
예제 #12
0
static int
png2vips_image( Read *read, VipsImage *out )
{
	int interlace_type = png_get_interlace_type( read->pPng, read->pInfo );
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );

	if( interlace_type != PNG_INTERLACE_NONE ) { 
		/* Arg awful interlaced image. We have to load to a huge mem 
		 * buffer, then copy to out.
		 */
		t[0] = vips_image_new_memory();
		if( png2vips_header( read, t[0] ) ||
			png2vips_interlace( read, t[0] ) ||
			vips_image_write( t[0], out ) )
			return( -1 );
	}
	else {
		t[0] = vips_image_new();
		if( png2vips_header( read, t[0] ) ||
			vips_image_generate( t[0], 
				NULL, png2vips_generate, NULL, 
				read, NULL ) ||
			vips_sequential( t[0], &t[1], 
				"tile_height", 8,
				"access", read->readbehind ? 
					VIPS_ACCESS_SEQUENTIAL : 
					VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
				NULL ) ||
			vips_image_write( t[1], out ) )
			return( -1 );
	}

	return( 0 );
}
예제 #13
0
파일: insert.c 프로젝트: ImageKit/libvips
/* The inverse: take ink to a vec of double. Used in the vips7 compat
 * wrappers. Result valid while im is valid. 
 */
double *
vips__ink_to_vector( const char *domain, VipsImage *im, VipsPel *ink, int *n )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( im ), 6 );

	double *result;

#ifdef VIPS_DEBUG
	printf( "vips__ink_to_vector: starting\n" );
#endif /*VIPS_DEBUG*/

	/* Wrap a VipsImage around ink.
	 */
	t[0] = vips_image_new_from_memory( ink, 
		1, 1, VIPS_IMAGE_SIZEOF_PEL( im ), VIPS_FORMAT_UCHAR );
	if( vips_copy( t[0], &t[1], 
		"bands", im->Bands, 
		"format", im->BandFmt, 
		"coding", im->Coding, 
		"interpretation", im->Type, 
		NULL ) )
		return( NULL ); 

	/* The image may be coded .. unpack to double.
	 */
	if( vips_image_decode( t[1], &t[2] ) ||
		vips_cast( t[2], &t[3], VIPS_FORMAT_DOUBLE, NULL ) )
		return( NULL );

	/* To a mem buffer, then copy to out. 
	 */
	if( !(t[4] = vips_image_new_memory()) ||
		vips_image_write( t[3], t[4] ) )
		return( NULL ); 

	if( !(result = VIPS_ARRAY( im, t[4]->Bands, double )) )
		return( NULL ); 
	memcpy( result, t[4]->data, VIPS_IMAGE_SIZEOF_PEL( t[4] ) ); 
	*n = t[4]->Bands; 

#ifdef VIPS_DEBUG
{
	int i;

	printf( "vips__ink_to_vector:\n" );
	printf( "\tink = " ); 
	for( i = 0; i < n; i++ )
		printf( "%d ", ink[i] );
	printf( "\n" ); 

	printf( "\tvec = " ); 
	for( i = 0; i < *n; i++ )
		printf( "%d ", result[i] );
	printf( "\n" ); 
}
#endif /*VIPS_DEBUG*/

	return( result ); 
}
예제 #14
0
/* Ref an operation for the cache. The operation itself, plus all the output 
 * objects it makes. 
 */
static void
vips_cache_ref( VipsOperation *operation )
{
	g_object_ref( operation );
	(void) vips_argument_map( VIPS_OBJECT( operation ),
		vips_object_ref_arg, NULL, NULL );
	vips_operation_touch( operation );
}
예제 #15
0
static void
vips_interpolate_finalize( GObject *gobject )
{
	printf( "vips_interpolate_finalize: " );
	vips_object_print( VIPS_OBJECT( gobject ) );

	G_OBJECT_CLASS( vips_interpolate_parent_class )->finalize( gobject );
}
예제 #16
0
파일: header.c 프로젝트: alon/libvips
/* Print header, or parts of header.
 */
static int
print_header( IMAGE *im, gboolean many )
{
	if( !main_option_field ) {
		printf( "%s: ", im->filename );

		vips_object_print_summary( VIPS_OBJECT( im ) );

		if( main_option_all )
			(void) vips_image_map( im, print_field_fn, &many );
	}
	else if( strcmp( main_option_field, "getext" ) == 0 ) {
		if( im__has_extension_block( im ) ) {
			void *buf;
			int size;

			if( !(buf = im__read_extension_block( im, &size )) )
				return( -1 );
			printf( "%s", (char *) buf );
			im_free( buf );
		}
	}
	else if( strcmp( main_option_field, "Hist" ) == 0 ) 
		printf( "%s", im_history_get( im ) );
	else {
		GValue value = { 0 };
		GType type;

		if( im_header_get( im, main_option_field, &value ) )
			return( -1 );

		/* Display the save form, if there is one. This way we display
		 * something useful for ICC profiles, xml fields, etc.
		 */
		type = G_VALUE_TYPE( &value );
		if( g_value_type_transformable( type, IM_TYPE_SAVE_STRING ) ) {
			GValue save_value = { 0 };

			g_value_init( &save_value, IM_TYPE_SAVE_STRING );
			if( !g_value_transform( &value, &save_value ) ) 
				return( -1 );
			printf( "%s\n", im_save_string_get( &save_value ) );
			g_value_unset( &save_value );
		}
		else {
			char *str_value;

			str_value = g_strdup_value_contents( &value );
			printf( "%s\n", str_value );
			g_free( str_value );
		}

		g_value_unset( &value );
	}

	return( 0 );
}
예제 #17
0
파일: bicubic.cpp 프로젝트: alon/libvips
static void
vips_interpolate_bicubic_init( VipsInterpolateBicubic *bicubic )
{
#ifdef DEBUG
	printf( "vips_interpolate_bicubic_init: " );
	vips_object_print( VIPS_OBJECT( bicubic ) );
#endif /*DEBUG*/

}
예제 #18
0
파일: jpeg2vips.c 프로젝트: Jondeen/libvips
/* Read a cinfo to a VIPS image.
 */
static int
read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
{
	struct jpeg_decompress_struct *cinfo = &jpeg->cinfo;
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );

	VipsImage *im;

	/* Here for longjmp() from vips__new_error_exit().
	 */
	if( setjmp( jpeg->eman.jmp ) ) 
		return( -1 );

	t[0] = vips_image_new();
	if( read_jpeg_header( jpeg, t[0] ) )
		return( -1 );

	jpeg_start_decompress( cinfo );

#ifdef DEBUG
	printf( "read_jpeg_image: starting decompress\n" );
#endif /*DEBUG*/

	if( vips_image_generate( t[0], 
		NULL, read_jpeg_generate, NULL, 
		jpeg, NULL ) ||
		vips_sequential( t[0], &t[1], 
			"tile_height", 8,
			"access", jpeg->readbehind ? 
				VIPS_ACCESS_SEQUENTIAL : 
				VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
			NULL ) )
		return( -1 );

	im = t[1];
	if( jpeg->autorotate )
		im = read_jpeg_rotate( VIPS_OBJECT( out ), im );

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

	return( 0 );
}
예제 #19
0
int
main( int argc, char **argv )
{
	GOptionContext *context;
	GError *error = NULL;
	int i;

	if( vips_init( argv[0] ) )
	        vips_error_exit( "unable to start VIPS" );
	textdomain( GETTEXT_PACKAGE );
	setlocale( LC_ALL, "" );

        context = g_option_context_new( _( "- thumbnail generator" ) );

	g_option_context_add_main_entries( context, options, GETTEXT_PACKAGE );
	g_option_context_add_group( context, vips_get_option_group() );

	if( !g_option_context_parse( context, &argc, &argv, &error ) ) {
		if( error ) {
			fprintf( stderr, "%s\n", error->message );
			g_error_free( error );
		}

		vips_error_exit( "try \"%s --help\"", g_get_prgname() );
	}

	g_option_context_free( context );

	if( sscanf( thumbnail_size, "%d x %d", 
		&thumbnail_width, &thumbnail_height ) != 2 ) {
		if( sscanf( thumbnail_size, "%d", &thumbnail_width ) != 1 ) 
			vips_error_exit( "unable to parse size \"%s\" -- "
				"use eg. 128 or 200x300", thumbnail_size );

		thumbnail_height = thumbnail_width;
	}

	for( i = 1; i < argc; i++ ) {
		/* Hang resources for processing this thumbnail off @process.
		 */
		VipsObject *process = VIPS_OBJECT( vips_image_new() ); 

		if( thumbnail_process( process, argv[i] ) ) {
			fprintf( stderr, "%s: unable to thumbnail %s\n", 
				argv[0], argv[i] );
			fprintf( stderr, "%s", vips_error_buffer() );
			vips_error_clear();
		}

		g_object_unref( process );
	}

	vips_shutdown();

	return( 0 );
}
예제 #20
0
// walk the options and set props on the operation 
void 
VOption::set_operation( VipsOperation *operation )
{
	std::list<Pair *>::iterator i;

	for( i = options.begin(); i != options.end(); ++i ) 
		if( (*i)->input ) {
#ifdef VIPS_DEBUG_VERBOSE
			printf( "set_operation: " );
			vips_object_print_name( VIPS_OBJECT( operation ) );
			char *str_value = g_strdup_value_contents( &(*i)->value );
			printf( ".%s = %s\n", (*i)->name, str_value );
			g_free( str_value );
#endif /*VIPS_DEBUG_VERBOSE*/

			set_property( VIPS_OBJECT( operation ),
				(*i)->name, &(*i)->value );
		}
}
예제 #21
0
static int
read_image( Read *read, VipsImage *out )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );
	guint64 length;
	void *data; 
	int fd;
	webp_decoder decoder;

	/* libwebp makes streaming very hard. We have to read to a full memory
	 * buffer, then copy to out.
	 *
	 * mmap the input file, it's slightly quicker.
	 */
	t[0] = vips_image_new_buffer();
	if( read_header( read, t[0] ) )
		return( -1 );
	if( vips_image_write_prepare( t[0] ) ) 
		return( -1 );

	if( !(fd = vips__open_image_read( read->filename )) )
		return( -1 );
	if( (length = vips_file_length( fd )) < 0 ) {
		vips_tracked_close( fd ); 
		return( -1 );
	}
	if( !(data = vips__mmap( fd, FALSE, length, 0 )) ) {
		vips_tracked_close( fd ); 
		return( -1 );
	}

	if( t[0]->Bands == 3 )
		decoder = WebPDecodeRGBInto;
	else
		decoder = WebPDecodeRGBAInto;

	if( !decoder( (uint8_t *) data, length, 
		VIPS_IMAGE_ADDR( t[0], 0, 0 ), 
		VIPS_IMAGE_SIZEOF_IMAGE( t[0] ),
		VIPS_IMAGE_SIZEOF_LINE( t[0] ) ) ) { 
		vips__munmap( data, length ); 
		vips_tracked_close( fd ); 
		vips_error( "webp2vips", "%s", _( "unable to read pixels" ) ); 
		return( -1 );
	}

	vips__munmap( data, length ); 
	vips_tracked_close( fd ); 

	if( vips_image_write( t[0], out ) )
		return( -1 );

	return( 0 );
}
예제 #22
0
// walk the options and fetch any requested outputs
void 
VOption::get_operation( VipsOperation *operation )
{
	std::list<Pair *>::iterator i;

	for( i = options.begin(); i != options.end(); ++i ) 
		if( ! (*i)->input ) {
			const char *name = (*i)->name;

			g_object_get_property( G_OBJECT( operation ),
				name, &(*i)->value );

#ifdef VIPS_DEBUG_VERBOSE
			printf( "get_operation: " );
			vips_object_print_name( VIPS_OBJECT( operation ) );
			char *str_value = g_strdup_value_contents( 
				&(*i)->value );
			printf( ".%s = %s\n", name, str_value );
			g_free( str_value );
#endif /*VIPS_DEBUG_VERBOSE*/

			GValue *value = &(*i)->value;
			GType type = G_VALUE_TYPE( value );

			if( type == VIPS_TYPE_IMAGE ) {
				// rebox object
				VipsImage *image = VIPS_IMAGE( 
					g_value_get_object( value ) );  
				*((*i)->vimage) = VImage( image ); 
			}
			else if( type == G_TYPE_INT ) 
				*((*i)->vint) = g_value_get_int( value ); 
			else if( type == G_TYPE_BOOLEAN ) 
				*((*i)->vbool) = g_value_get_boolean( value ); 
			else if( type == G_TYPE_DOUBLE ) 
				*((*i)->vdouble) = g_value_get_double( value ); 
			else if( type == VIPS_TYPE_ARRAY_DOUBLE ) {
				int length;
				double *array = 
					vips_value_get_array_double( value, 
					&length );
				int j;

				((*i)->vvector)->resize( length ); 
				for( j = 0; j < length; j++ )
					(*((*i)->vvector))[j] = array[j];
			}
			else if( type == VIPS_TYPE_BLOB ) {
				// our caller gets a reference
				*((*i)->vblob) = 
					(VipsBlob *) g_value_dup_boxed( value );
			}
		}
}
예제 #23
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 );
}
예제 #24
0
static void *
vips_cache_print_fn( void *value, void *a, void *b )
{
	char str[32768];
	VipsBuf buf = VIPS_BUF_STATIC( str );

	vips_object_to_string( VIPS_OBJECT( value ), &buf );

	printf( "%p - %s\n", value, vips_buf_all( &buf ) );

	return( NULL );
}
예제 #25
0
파일: fits.c 프로젝트: FlavioFalcao/libvips
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 );
}
예제 #26
0
파일: smartcrop.c 프로젝트: jcupitt/libvips
static int
vips_smartcrop_score( VipsSmartcrop *smartcrop, VipsImage *in, 
	int left, int top, int width, int height, double *score )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( smartcrop ), 2 );

	if( vips_extract_area( in, &t[0], left, top, width, height, NULL ) ||
		vips_hist_find( t[0], &t[1], NULL ) ||
		vips_hist_entropy( t[1], score, NULL ) )
		return( -1 );

	return( 0 );
}
예제 #27
0
/* Are two objects equal, ie. have the same inputs.
 */
static gboolean 
vips_operation_equal( VipsOperation *a, VipsOperation *b )
{
	if( a == b ) 
		return( TRUE );

	if( G_OBJECT_TYPE( a ) == G_OBJECT_TYPE( b ) &&
		vips_operation_hash( a ) == vips_operation_hash( b ) &&
		!vips_argument_map( VIPS_OBJECT( a ), 
			vips_object_equal_arg, b, NULL ) )
		return( TRUE );

	return( FALSE );
}
예제 #28
0
static void *
vips_cache_print_fn( void *value, void *a, void *b )
{
	VipsOperationCacheEntry *entry = value;

	char str[32768];
	VipsBuf buf = VIPS_BUF_STATIC( str );

	vips_object_to_string( VIPS_OBJECT( entry->operation ), &buf );

	printf( "%p - %s\n", value, vips_buf_all( &buf ) );

	return( NULL );
}
예제 #29
0
파일: convi.c 프로젝트: jcupitt/libvips
static void
vips_convi_dispose( GObject *gobject )
{
	VipsConvi *convi = (VipsConvi *) gobject;

#ifdef DEBUG
	printf( "vips_convi_dispose: " );
	vips_object_print_name( VIPS_OBJECT( gobject ) );
	printf( "\n" );
#endif /*DEBUG*/

	vips_convi_compile_free( convi ); 

	G_OBJECT_CLASS( vips_convi_parent_class )->dispose( gobject );
}
예제 #30
0
파일: fitsload.c 프로젝트: jcupitt/libvips
static int
vips_foreign_load_fits_load( VipsForeignLoad *load )
{
	VipsForeignLoadFits *fits = (VipsForeignLoadFits *) load;
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( fits ), 2 );

	t[0] = vips_image_new();
	if( vips__fits_read( fits->filename, t[0] ) || 
		vips_flip( t[0], &t[1], VIPS_DIRECTION_VERTICAL, NULL ) ||
		vips_image_write( t[1], load->real ) )
		return( -1 );

	return( 0 );
}