Example #1
0
/* Split filename into name / mode components. name and mode should both be
 * FILENAME_MAX chars.
 *
 * We look for the ':' splitting the name and mode by searching for the
 * rightmost occurence of the regexp ".[A-Za-z0-9]+:". Example: consider the
 * horror that is
 *
 * 	c:\silly:dir:name\fr:ed.tif:jpeg:95,,,,c:\icc\srgb.icc
 *
 */
void
vips_filename_split( const char *path, char *name, char *mode )
{
        char *p;

        vips_strncpy( name, path, FILENAME_MAX );

	/* Search back towards start stopping at each ':' char.
	 */
	for( p = name + strlen( name ) - 1; p > name; p -= 1 )
		if( *p == ':' ) {
			char *q;

			for( q = p - 1; isalnum( *q ) && q > name; q -= 1 )
				;

			if( *q == '.' )
				break;
		}

	if( *p == ':' ) {
                vips_strncpy( mode, p + 1, FILENAME_MAX );
                *p = '\0';
        }
        else
                strcpy( mode, "" );
}
Example #2
0
/* Find the prefix part of a dir ... name is the name of this prog from argv0.
 *
 * dir					name		guess prefix
 *
 * /home/john/vips-7.6.4/bin/vips-7.6	vips-7.6	/home/john/vips-7.6.4
 * /usr/local/bin/ip			ip		/usr/local
 *
 * all other forms ... return NULL.
 */
static char *
extract_prefix( const char *dir, const char *name )
{
	char edir[PATH_MAX];
	char vname[PATH_MAX];
	int i;

#ifdef DEBUG
	printf( "extract_prefix: trying for dir = \"%s\", name = \"%s\"\n", 
		dir, name );
#endif /*DEBUG*/

	/* Is dir relative? Prefix with cwd.
	 */
	if( !g_path_is_absolute( dir ) ) {
		vips_snprintf( edir, PATH_MAX, "%s" G_DIR_SEPARATOR_S "%s",
			get_current_dir(), dir );
	}
	else {
		vips_strncpy( edir, dir, PATH_MAX );
	}

	/* Chop off the trailing prog name, plus the trailing
	 * G_DIR_SEPARATOR_S.
	 */
	if( !vips_ispostfix( edir, name ) ) 
		return( NULL );
	vips_strncpy( vname, edir, PATH_MAX );
	vname[strlen( edir ) - strlen( name ) - 1] = '\0';

	/* Remove any "/./", any trailing "/.", any trailing "/".
	 */
	for( i = 0; i < (int) strlen( vname ); i++ ) 
		if( vips_isprefix( G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S, 
			vname + i ) )
			memcpy( vname + i, vname + i + 2, 
				strlen( vname + i + 2 ) + 1 );
	if( vips_ispostfix( vname, G_DIR_SEPARATOR_S "." ) )
		vname[strlen( vname ) - 2] = '\0';
	if( vips_ispostfix( vname, G_DIR_SEPARATOR_S ) )
		vname[strlen( vname ) - 1] = '\0';

#ifdef DEBUG
	printf( "extract_prefix: canonicalised path = \"%s\"\n", vname );
#endif /*DEBUG*/

	/* Ought to be a "/bin" at the end now.
	 */
	if( !vips_ispostfix( vname, G_DIR_SEPARATOR_S "bin" ) ) 
		return( NULL );
	vname[strlen( vname ) - strlen( G_DIR_SEPARATOR_S "bin" )] = '\0';

#ifdef DEBUG
	printf( "extract_prefix: found \"%s\"\n", vname );
#endif /*DEBUG*/

	return( vips_strdup( NULL, vname ) );
}
Example #3
0
/* Split a vips8-style filename + options.
 *
 * filename and option_string must be VIPS_PATH_MAX in length. 
 */
void
vips__filename_split8( const char *name, char *filename, char *option_string )
{
	char *p;

	vips_strncpy( filename, name, VIPS_PATH_MAX );
	if( (p = (char *) vips__find_rightmost_brackets( filename )) ) {
		vips_strncpy( option_string, p, VIPS_PATH_MAX );
		*p = '\0';
	}
	else
		vips_strncpy( option_string, "", VIPS_PATH_MAX );
}
Example #4
0
/* Wrapper over (v)snprintf() ... missing on old systems.
 */
int
vips_vsnprintf( char *str, size_t size, const char *format, va_list ap )
{
#ifdef HAVE_VSNPRINTF
	return( vsnprintf( str, size, format, ap ) );
#else /*HAVE_VSNPRINTF*/
	/* Bleurg!
	 */
	int n;
	static char buf[MAX_BUF];

	if( size > MAX_BUF )
		vips_error_exit( "panic: buffer overflow "
			"(request to write %d bytes to buffer of %d bytes)",
			size, MAX_BUF );
	n = vsprintf( buf, format, ap );
	if( n > MAX_BUF )
		vips_error_exit( "panic: buffer overflow "
			"(%d bytes written to buffer of %d bytes)",
			n, MAX_BUF );

	vips_strncpy( str, buf, size );

	return( n );
#endif /*HAVE_VSNPRINTF*/
}
Example #5
0
/* Wrapper over (v)snprintf() ... missing on old systems.
 */
int
vips_vsnprintf( char *str, size_t size, const char *format, va_list ap )
{
#ifdef HAVE_VSNPRINTF
	return( vsnprintf( str, size, format, ap ) );
#else /*HAVE_VSNPRINTF*/
	/* Bleurg!
	 */
	int n;
	static char buf[MAX_BUF];

	/* We can't return an error code, we may already have trashed the
	 * stack. We must stop immediately.
	 */
	if( size > MAX_BUF )
		vips_error_exit( "panic: buffer overflow "
			"(request to write %d bytes to buffer of %d bytes)",
			size, MAX_BUF );
	n = vsprintf( buf, format, ap );
	if( n > MAX_BUF )
		vips_error_exit( "panic: buffer overflow "
			"(%d bytes written to buffer of %d bytes)",
			n, MAX_BUF );

	vips_strncpy( str, buf, size );

	return( n );
#endif /*HAVE_VSNPRINTF*/
}
Example #6
0
/* Look for a file along PATH. If we find it, look for an enclosing prefix.
 */
static char *
find_file( const char *name )
{
	const char *path = g_getenv( "PATH" );
	char *prefix;
	char full_path[PATH_MAX];

	if( !path )
		return( NULL );

#ifdef DEBUG
	printf( "vips_guess_prefix: g_getenv( \"PATH\" ) == \"%s\"\n", path );
#endif /*DEBUG*/

#ifdef OS_WIN32
	/* Windows always searches '.' first, so prepend cwd to path.
	 */
	vips_snprintf( full_path, PATH_MAX, "%s" G_SEARCHPATH_SEPARATOR_S "%s",
		get_current_dir(), path );
#else /*!OS_WIN32*/
	vips_strncpy( full_path, path, PATH_MAX );
#endif /*OS_WIN32*/

	if( (prefix = scan_path( full_path, name )) ) 
		return( prefix );

	return( NULL );
}
Example #7
0
/* Given (eg.) "/poop/somefile.png", write @im to the thumbnail name,
 * (eg.) "/poop/tn_somefile.jpg".
 */
static int
thumbnail_write( VipsObject *process, VipsImage *im, const char *filename )
{
	char *file;
	char *p;
	char buf[FILENAME_MAX];
	char *output_name;

	file = g_path_get_basename( filename );

	/* Remove the suffix from the file portion.
	 */
	if( (p = strrchr( file, '.' )) ) 
		*p = '\0';

	/* Don't use vips_snprintf(), we only want to optionally substitute a 
	 * single %s.
	 */
	vips_strncpy( buf, output_format, FILENAME_MAX ); 
	vips__substitute( buf, FILENAME_MAX, file ); 

	/* output_format can be an absolute path, in which case we discard the
	 * path from the incoming file.
	 */
	if( g_path_is_absolute( output_format ) ) 
		output_name = g_strdup( buf );
	else {
		char *dir;

		dir = g_path_get_dirname( filename );
		output_name = g_build_filename( dir, buf, NULL );
		g_free( dir );
	}

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

	g_free( file );

	if( vips_image_write_to_file( im, output_name, NULL ) ) {
		g_free( output_name );
		return( -1 );
	}
	g_free( output_name );

	return( 0 );
}
Example #8
0
/* Fetch a token. If it's a string token terminated by a '[', fetch up to the
 * matching ']' as well, for example ".jpg[Q=90]".
 *
 * Return NULL for end of tokens.
 */
const char *
vips__token_segment( const char *p, VipsToken *token, 
	char *string, int size )
{
	const char *q;

	if( !(q = vips__token_must( p, token, string, size )) )
		return( NULL ); 

	/* If we stopped on [, read up to the matching ]. 
	 */
	if( *token == VIPS_TOKEN_STRING &&
		q[0] == '[' ) {
		VipsToken sub_token;
		char sub_string[VIPS_PATH_MAX];
		int depth;
		int i; 

		depth = 0;
		do {
			if( !(q = vips__token_must( q, &sub_token, 
				sub_string, VIPS_PATH_MAX )) )
				return( NULL ); 

			switch( sub_token ) {
			case VIPS_TOKEN_LEFT:
				depth += 1;
				break;

			case VIPS_TOKEN_RIGHT:
				depth -= 1;
				break;

			default:
				break;
			}
		} while( !(sub_token == VIPS_TOKEN_RIGHT && depth == 0) );

		i = VIPS_MIN( q - p, size );
		vips_strncpy( string, p, i + 1 );
	}

	return( q ); 
}
Example #9
0
/** 
 * vips_guess_prefix:
 * @argv0: program name (typically argv[0])
 * @env_name: save prefix in this environment variable
 *
 * vips_guess_prefix() tries to guess the install directory. You should pass 
 * in the value of argv[0] (the name your program was run as) as a clue to 
 * help it out, plus the name of the environment variable you let the user 
 * override your package install area with (eg. "VIPSHOME"). 
 *
 * On success, vips_guess_prefix() returns the prefix it discovered, and as a 
 * side effect, sets the environment variable (if it's not set).
 *
 * Don't free the return string!
 * 
 * See also: vips_guess_libdir().
 *
 * Returns: (transfer none): the install prefix as a static string, do not free.
 */
const char *
vips_guess_prefix( const char *argv0, const char *env_name )
{
        const char *prefix;
        char *basename;
        char name[VIPS_PATH_MAX];

	/* Already set?
	 */
        if( (prefix = g_getenv( env_name )) ) {
#ifdef DEBUG
		printf( "vips_guess_prefix: found \"%s\" in environment\n", 
			prefix );
#endif /*DEBUG*/
                return( prefix );
	}

	/* Get the program name from argv0.
	 */
	basename = g_path_get_basename( argv0 );

	/* Add the exe suffix, if it's missing.
	 */
	if( strlen( VIPS_EXEEXT ) > 0 ) {
		const char *olds[] = { VIPS_EXEEXT };

		vips__change_suffix( basename, name, 
			VIPS_PATH_MAX, VIPS_EXEEXT, olds, 1 );
	}
	else
		vips_strncpy( name, basename, VIPS_PATH_MAX );

	g_free( basename ); 

#ifdef DEBUG
	printf( "vips_guess_prefix: argv0 = %s\n", argv0 );
	printf( "vips_guess_prefix: name = %s\n", name );
#endif /*DEBUG*/

	prefix = guess_prefix( argv0, name );
	g_setenv( env_name, prefix, TRUE );

	return( prefix );
}
Example #10
0
static Read *
read_new( const char *filename, VipsImage *im )
{
	Read *read;
	static int inited = 0;

	if( !inited ) {
#ifdef HAVE_MAGICKCOREGENESIS
		MagickCoreGenesis( vips_get_argv0(), MagickFalse );
#else /*!HAVE_MAGICKCOREGENESIS*/
		InitializeMagick( "" );
#endif /*HAVE_MAGICKCOREGENESIS*/
		inited = 1;
	}

	if( !(read = VIPS_NEW( im, Read )) )
		return( NULL );
	read->filename = g_strdup( filename );
	read->im = im;
	read->image = NULL;
	read->image_info = CloneImageInfo( NULL );
	GetExceptionInfo( &read->exception );
	read->n_frames = 0;
	read->frames = NULL;
	read->frame_height = 0;
	read->lock = g_mutex_new();

	g_signal_connect( im, "close", G_CALLBACK( read_destroy ), read );

	if( !read->image_info ) 
		return( NULL );

	vips_strncpy( read->image_info->filename, filename, MaxTextExtent );

#ifdef DEBUG
	printf( "magick2vips: read_new: %s\n", read->filename );
#endif /*DEBUG*/

	return( read );
}
Example #11
0
/* Break a command-line argument into tokens separated by whitespace. 
 *
 * Strings can't be adjacent, so "hello world" (without quotes) is a single 
 * string.  Strings are written (with \" escaped) into @string. If the string
 * is larger than @size, it is silently null-termionated and truncated. 
 *
 * Return NULL for end of tokens.
 */
const char *
vips__token_get( const char *p, VipsToken *token, char *string, int size )
{
	const char *q;
	int ch;
	int n;
	int i;

	/* Parse this token with p.
	 */
	if( !p )
		return( NULL );

	/* Skip initial whitespace.
	 */
        p += strspn( p, " \t\n\r" );
	if( !p[0] )
		return( NULL );

	switch( (ch = p[0]) ) {
	case '{':
	case '[':
	case '(':
	case '<':
		*token = VIPS_TOKEN_LEFT;
		p += 1;
		break;

	case ')':
	case ']':
	case '}':
	case '>':
		*token = VIPS_TOKEN_RIGHT;
		p += 1;
		break;

	case '=':
		*token = VIPS_TOKEN_EQUALS;
		p += 1;
		break;

	case ',':
		*token = VIPS_TOKEN_COMMA;
		p += 1;
		break;

	case '"':
	case '\'':
		/* Parse a quoted string. Copy up to ", interpret any \",
		 * error if no closing ".
		 */
		*token = VIPS_TOKEN_STRING;

		do {
			/* Number of characters until the next quote
			 * character or end of string.
			 */
			if( (q = strchr( p + 1, ch )) )
				n = q - p + 1;
			else
				n = strlen( p + 1 );

			/* How much can we copy to the buffer?
			 */
			i = VIPS_MIN( n, size );
			vips_strncpy( string, p + 1, i );

			/* We might have stopped at an escaped quote. If the
			 * string was not truncated, swap the preceding 
			 * backslash for a quote.
			 */
			if( p[n + 1] == ch && p[n] == '\\' && i == n )
				string[i - 1] = ch;

			string += i;
			size -= i;
			p += n + 1;
		} while( p[0] && p[-1] == '\\' );

		p += 1;

		break;

	default:
		/* It's an unquoted string: read up to the next non-string
		 * character. We don't allow two strings next to each other,
		 * so the next break must be bracket, equals, comma.
		 */
		*token = VIPS_TOKEN_STRING;
		n = strcspn( p, "<[{()}]>=," );
		i = VIPS_MIN( n, size );
		vips_strncpy( string, p, i + 1 );
		p += n;

		/* We remove leading whitespace, so we trim trailing
		 * whitespace from unquoted strings too. Only if the string
		 * hasn't been truncated.
		 */
		if( i == n ) 
			while( i > 0 && isspace( string[i - 1] ) ) {
				string[i - 1] = '\0';
				i--;
			}

		break;
	}

	return( p );
}
Example #12
0
static Read *
read_new( const char *filename, VipsImage *im, 
	gboolean all_frames, const char *density, int page )
{
	Read *read;
	static int inited = 0;

	if( !inited ) {
#ifdef HAVE_MAGICKCOREGENESIS
		MagickCoreGenesis( vips_get_argv0(), MagickFalse );
#else /*!HAVE_MAGICKCOREGENESIS*/
		InitializeMagick( "" );
#endif /*HAVE_MAGICKCOREGENESIS*/
		inited = 1;
	}

	if( !(read = VIPS_NEW( im, Read )) )
		return( NULL );
	read->filename = filename ? g_strdup( filename ) : NULL;
	read->all_frames = all_frames;
	read->page = page;
	read->im = im;
	read->image = NULL;
	read->image_info = CloneImageInfo( NULL );
	GetExceptionInfo( &read->exception );
	read->n_frames = 0;
	read->frames = NULL;
	read->frame_height = 0;
	read->lock = vips_g_mutex_new();

	g_signal_connect( im, "close", G_CALLBACK( read_close ), read );

	if( !read->image_info ) 
		return( NULL );

	if( filename ) 
		vips_strncpy( read->image_info->filename, 
			filename, MaxTextExtent );

	/* Canvas resolution for rendering vector formats like SVG.
	 */
	VIPS_SETSTR( read->image_info->density, density );

#ifdef HAVE_SETIMAGEOPTION
	/* When reading DICOM images, we want to ignore any
	 * window_center/_width setting, since it may put pixels outside the
	 * 0-65535 range and lose data. 
	 *
	 * These window settings are attached as vips metadata, so our caller
	 * can interpret them if it wants.
	 */
  	SetImageOption( read->image_info, "dcm:display-range", "reset" );
#endif /*HAVE_SETIMAGEOPTION*/

	if( !all_frames ) {
#ifdef HAVE_NUMBER_SCENES 
		 /* I can't find docs for these fields, but this seems to work.
		  */
		char page[256];

		read->image_info->scene = read->page;
		read->image_info->number_scenes = 1;

		/* Some IMs must have the string version set as well.
		 */
		vips_snprintf( page, 256, "%d", read->page );
		read->image_info->scenes = strdup( page );
#else /*!HAVE_NUMBER_SCENES*/
		/* This works with GM 1.2.31 and probably others.
		 */
		read->image_info->subimage = read->page;
		read->image_info->subrange = 1;
#endif
	}

#ifdef DEBUG
	printf( "magick2vips: read_new: %s\n", read->filename );
#endif /*DEBUG*/

	return( read );
}