1 /* Start up the world of vips.
2  *
3  * 7/1/04 JC
4  *	- 1st version
5  * 7/6/05
6  * 	- g_type_init() too, so we can use gobject
7  * 2/9/06
8  * 	- also set g_prg_name() and load plugins
9  * 8/12/06
10  * 	- add liboil support
11  * 5/2/07
12  * 	- stop a loop if we're called recursively during VIPS startup ... it
13  * 	  can happen if (for example) vips_guess_prefix() fails and tries to
14  * 	  i18n an error message (thanks Christian)
15  * 8/6/07
16  * 	- just warn if plugins fail to load correctly: too annoying to have
17  * 	  VIPS refuse to start because of a dodgy plugin
18  * 7/11/07
19  * 	- progress feedback option
20  * 5/8/08
21  * 	- load plugins from libdir/vips-x.x
22  * 5/10/09
23  * 	- gtkdoc comments
24  * 14/3/10
25  * 	- init image and region before we start, we need all types to be fully
26  * 	  constructed before we go parallel
27  * 18/9/16
28  * 	- call _setmaxstdio() on win32
29  * 4/8/17
30  * 	- hide warnings is VIPS_WARNING is set
31  * 20/4/19
32  * 	- set the min stack, if we can
33  * 17/9/21
34  * 	- don't use atexit for cleanup, it's too unreliable ... users should
35  * 	  call vips_shutdown explicitly if they want a clean exit, though a
36  * 	  dirty exit is fine
37  */
38 
39 /*
40 
41     This file is part of VIPS.
42 
43     VIPS is free software; you can redistribute it and/or modify
44     it under the terms of the GNU Lesser General Public License as published by
45     the Free Software Foundation; either version 2 of the License, or
46     (at your option) any later version.
47 
48     This program is distributed in the hope that it will be useful,
49     but WITHOUT ANY WARRANTY; without even the implied warranty of
50     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
51     GNU Lesser General Public License for more details.
52 
53     You should have received a copy of the GNU Lesser General Public License
54     along with this program; if not, write to the Free Software
55     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
56     02110-1301  USA
57 
58  */
59 
60 /*
61 
62     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
63 
64  */
65 
66 /*
67 #define DEBUG
68  */
69 
70 /* pthread_setattr_default_np() is a non-portable GNU extension.
71  */
72 #define _GNU_SOURCE
73 
74 #ifdef HAVE_CONFIG_H
75 #include <config.h>
76 #endif /*HAVE_CONFIG_H*/
77 #include <vips/intl.h>
78 
79 #ifdef HAVE_PTHREAD_DEFAULT_NP
80 #include <pthread.h>
81 #endif /*HAVE_PTHREAD_DEFAULT_NP*/
82 
83 #include <stdio.h>
84 #include <stdlib.h>
85 #ifdef HAVE_SYS_PARAM_H
86 #include <sys/param.h>
87 #endif /*HAVE_SYS_PARAM_H*/
88 #ifdef HAVE_UNISTD_H
89 #include <unistd.h>
90 #endif /*HAVE_UNISTD_H*/
91 #ifdef HAVE_DIRECT_H
92 #include <direct.h>
93 #endif /*HAVE_DIRECT_H*/
94 #include <limits.h>
95 #include <string.h>
96 
97 /* Disable deprecation warnings from gsf. There are loads, and still not
98  * patched as of 12/2020.
99  */
100 #ifdef HAVE_GSF
101 #pragma GCC diagnostic push
102 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
103 #include <gsf/gsf.h>
104 #pragma GCC diagnostic pop
105 #endif /*HAVE_GSF*/
106 
107 #include <vips/vips.h>
108 #include <vips/thread.h>
109 #include <vips/internal.h>
110 #include <vips/vector.h>
111 
112 #if ENABLE_DEPRECATED
113 #include <vips/vips7compat.h>
114 #endif
115 
116 /* abort() on the first warning or error.
117  */
118 int vips__fatal = 0;
119 
120 /* Use in various small places where we need a mutex and it's not worth
121  * making a private one.
122  */
123 GMutex *vips__global_lock = NULL;
124 
125 /* A debugging timer, zero at library init.
126  */
127 GTimer *vips__global_timer = NULL;
128 
129 /* Keep a copy of the argv0 here.
130  */
131 static char *vips__argv0 = NULL;
132 
133 /* Keep a copy of the last component of argv0 here.
134  */
135 static char *vips__prgname = NULL;
136 
137 /* Leak check on exit.
138  */
139 int vips__leak = 0;
140 
141 #ifdef DEBUG_LEAK
142 /* Count pixels processed per image here.
143  */
144 GQuark vips__image_pixels_quark = 0;
145 #endif /*DEBUG_LEAK*/
146 
147 static gint64 vips_pipe_read_limit = 1024 * 1024 * 1024;
148 
149 /**
150  * vips_get_argv0:
151  *
152  * See also: VIPS_INIT().
153  *
154  * Returns: (transfer none): a pointer to an internal copy of the
155  * argv0 string passed to
156  * VIPS_INIT(). Do not free this value
157  */
158 const char *
vips_get_argv0(void)159 vips_get_argv0( void )
160 {
161 	return( vips__argv0 );
162 }
163 
164 /**
165  * vips_get_prgname:
166  *
167  * Return the program name. This can be useful for the user tio see,.
168  *
169  * See also: VIPS_INIT().
170  *
171  * Returns: (transfer none): a pointer to an internal copy of the program
172  * name. Do not free this value
173  */
174 const char *
vips_get_prgname(void)175 vips_get_prgname( void )
176 {
177 	const char *prgname;
178 
179 	if( (prgname = g_get_prgname()) )
180 		return( prgname );
181 	else
182 		return( vips__prgname );
183 }
184 
185 /**
186  * VIPS_INIT:
187  * @ARGV0: name of application
188  *
189  * gtk-doc mistakenly tags this macro as deprecated for unknown reasons. It is
190  * *NOT* deprecated, please ignore the warning above.
191  *
192  * VIPS_INIT() starts up the world of VIPS. You should call this on
193  * program startup before using any other VIPS operations. If you do not call
194  * VIPS_INIT(), VIPS will call it for you when you use your first VIPS
195  * operation, but it may not be able to get hold of @ARGV0 and VIPS may
196  * therefore be unable to find its data files. It is much better to call
197  * this macro yourself.
198  *
199  * @ARGV0 is used to help discover message catalogues if libvips has been
200  * relocated. If you don't need a relocatable package, you can just pass `""`
201  * and it'll be fine.
202  *
203  * Additionally, VIPS_INIT() can be run from any thread, but it must not be
204  * called from more than one thread at the same time. This is much easier to
205  * guarantee if you call it yourself.
206  *
207  * VIPS_INIT() is a macro, since it tries to check ABI compatibility
208  * between the caller and the library. You can also call vips_init(), the
209  * non-macro version, if macros are not available to you.
210  *
211  * You may call VIPS_INIT() many times and vips_shutdown() many times, but you
212  * must not call VIPS_INIT() after vips_shutdown(). In other words, you cannot
213  * stop and restart vips.
214  *
215  * Use the environment variable `VIPS_MIN_STACK_SIZE` to set the minimum stack
216  * size. For example, `2m` for a minimum of two megabytes of stack. This can
217  * be important for systems like musl where the default stack is very small.
218  *
219  * VIPS_INIT() does approximately the following:
220  *
221  * + checks that the libvips your program is expecting is
222  *   binary-compatible with the vips library you're running against
223  *
224  * + sets a minimum stack size, see above
225  *
226  * + initialises any libraries that VIPS is using, including GObject
227  *   and the threading system, if neccessary
228  *
229  * + guesses where the VIPS data files are and sets up
230  *   internationalisation --- see vips_guess_prefix()
231  *
232  * + creates the main vips types, including #VipsImage and friends
233  *
234  * + loads any plugins from $libdir/vips-x.y/, where x and y are the
235  *   major and minor version numbers for this VIPS.
236  *
237  * Example:
238  *
239  * |[
240  * int main (int argc, char **argv)
241  * {
242  *   if (VIPS_INIT (argv[0]))
243  *     vips_error_exit ("unable to start VIPS");
244  *
245  *   vips_shutdown ();
246  *
247  *   return 0;
248  * }
249  * ]|
250  *
251  * See also: vips_shutdown(), vips_add_option_entries(), vips_version(),
252  * vips_guess_prefix(), vips_guess_libdir().
253  *
254  * Returns: 0 on success, -1 otherwise
255  */
256 
257 /* Load all plugins in a directory ... look for '.<G_MODULE_SUFFIX>' or
258  * '.plg' (deprecated) suffix. Error if we had any probs.
259  */
260 static int
vips_load_plugins(const char * fmt,...)261 vips_load_plugins( const char *fmt, ... )
262 {
263         va_list ap;
264         char dir_name[VIPS_PATH_MAX];
265         GDir *dir;
266 	const char *name;
267         int result;
268 
269 	/* Silently succeed if we can't do modules.
270 	 */
271 	if( !g_module_supported() )
272 		return( 0 );
273 
274         va_start( ap, fmt );
275         (void) vips_vsnprintf( dir_name, VIPS_PATH_MAX - 1, fmt, ap );
276         va_end( ap );
277 
278 	g_info( "searching \"%s\"", dir_name );
279 
280         if( !(dir = g_dir_open( dir_name, 0, NULL )) )
281 		/* Silent success for dir not there.
282 		 */
283                 return( 0 );
284 
285         result = 0;
286         while( (name = g_dir_read_name( dir )) )
287                 if( vips_ispostfix( name, "." G_MODULE_SUFFIX )
288 #if ENABLE_DEPRECATED
289 				|| vips_ispostfix( name, ".plg" )
290 #endif
291 			) {
292 			char path[VIPS_PATH_MAX];
293 			GModule *module;
294 
295 			vips_snprintf( path, VIPS_PATH_MAX - 1,
296 				"%s" G_DIR_SEPARATOR_S "%s", dir_name, name );
297 
298 			g_info( "loading \"%s\"", path );
299 
300 			module = g_module_open( path, G_MODULE_BIND_LAZY );
301 			if( !module ) {
302 				g_warning( _( "unable to load \"%s\" -- %s" ),
303 					path, g_module_error() );
304 				result = -1;
305 			}
306 
307 			/* Modules will almost certainly create new types, so
308 			 * they can't be unloaded.
309 			 */
310 			g_module_make_resident( module );
311                 }
312         g_dir_close( dir );
313 
314 	return( result );
315 }
316 
317 /* Install this log handler to hide warning messages.
318  */
319 static void
empty_log_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer user_data)320 empty_log_handler( const gchar *log_domain, GLogLevelFlags log_level,
321 	const gchar *message, gpointer user_data )
322 {
323 }
324 
325 /* Attempt to set a minimum stacksize. This can be important on systems with a
326  * very low default, like musl.
327  */
328 static void
set_stacksize(guint64 size)329 set_stacksize( guint64 size )
330 {
331 #ifdef HAVE_PTHREAD_DEFAULT_NP
332 	pthread_attr_t attr;
333 	size_t cur_stack_size;
334 
335 	/* Don't allow stacks less than 2mb.
336 	 */
337 	size = VIPS_MAX( size, 2 * 1024 * 1024 );
338 
339 	if( pthread_attr_init( &attr ) ||
340 		pthread_attr_getstacksize( &attr, &cur_stack_size ) ) {
341 		g_warning( "set_stacksize: unable to get stack size" );
342 		return;
343 	}
344 
345 	if( cur_stack_size < size ) {
346 		if( pthread_attr_setstacksize( &attr, size ) ||
347 			pthread_setattr_default_np( &attr ) )
348 			g_warning( "set_stacksize: unable to set stack size" );
349 		else
350 			g_info( "set stack size to %" G_GUINT64_FORMAT "k",
351 				size / (guint64) 1024 );
352 	}
353 #endif /*HAVE_PTHREAD_DEFAULT_NP*/
354 }
355 
356 static void
vips_verbose(void)357 vips_verbose( void )
358 {
359 	const char *old;
360 
361 	old = g_getenv( "G_MESSAGES_DEBUG" );
362 
363 	if( !old )
364 		g_setenv( "G_MESSAGES_DEBUG", G_LOG_DOMAIN, TRUE );
365 	else if( !g_str_equal( old, "all" ) &&
366 		!g_strrstr( old, G_LOG_DOMAIN ) ) {
367 		char *new;
368 
369 		new = g_strconcat( old, " ", G_LOG_DOMAIN, NULL );
370 		g_setenv( "G_MESSAGES_DEBUG", new, TRUE );
371 
372 		g_free( new );
373 	}
374 }
375 
376 static int
vips_leak(void)377 vips_leak( void )
378 {
379 	char txt[1024];
380 	VipsBuf buf = VIPS_BUF_STATIC( txt );
381 	int n_leaks;
382 
383 	n_leaks = 0;
384 
385 	n_leaks += vips__object_leak();
386 	n_leaks += vips__type_leak();
387 	n_leaks += vips_tracked_get_allocs();
388 	n_leaks += vips_tracked_get_mem();
389 	n_leaks += vips_tracked_get_files();
390 
391 	if( vips_tracked_get_allocs() ||
392 		vips_tracked_get_mem() ||
393 		vips_tracked_get_files() ) {
394 		vips_buf_appendf( &buf, "memory: %d allocations, %zd bytes\n",
395 			vips_tracked_get_allocs(), vips_tracked_get_mem() );
396 		vips_buf_appendf( &buf, "files: %d open\n",
397 			vips_tracked_get_files() );
398 	}
399 
400 	vips_buf_appendf( &buf, "memory: high-water mark " );
401 	vips_buf_append_size( &buf, vips_tracked_get_mem_highwater() );
402 	vips_buf_appends( &buf, "\n" );
403 
404 	if( strlen( vips_error_buffer() ) > 0 ) {
405 		vips_buf_appendf( &buf, "error buffer: %s",
406 			vips_error_buffer() );
407 		n_leaks += strlen( vips_error_buffer() );
408 	}
409 
410 	fprintf( stderr, "%s", vips_buf_all( &buf ) );
411 
412 	n_leaks += vips__print_renders();
413 
414 #ifdef DEBUG
415 	vips_buffer_dump_all();
416 #endif /*DEBUG*/
417 
418 	return( n_leaks );
419 }
420 
421 /* This is not guaranteed to be called, and might be called after many parts
422  * of libvips have been freed. Threads can be in an indeterminate state.
423  * You must be very careful to avoid segvs.
424  */
425 static void
vips__atexit(void)426 vips__atexit( void )
427 {
428 	/* In dev releases, always show leaks. But not more than once, it's
429 	 * annoying.
430 	 */
431 #ifndef DEBUG_LEAK
432 	if( vips__leak )
433 #endif /*DEBUG_LEAK*/
434 	{
435 		static gboolean done = FALSE;
436 
437 		if( !done ) {
438 			done = TRUE;
439 			vips_cache_drop_all();
440 			vips_leak();
441 		}
442 	}
443 }
444 
445 /**
446  * vips_init:
447  * @argv0: name of application
448  *
449  * This function starts up libvips, see VIPS_INIT().
450  *
451  * This function is for bindings which need to start up vips. C programs
452  * should use the VIPS_INIT() macro, which does some extra checks.
453  *
454  * See also: VIPS_INIT().
455  *
456  * Returns: 0 on success, -1 otherwise
457  */
458 int
vips_init(const char * argv0)459 vips_init( const char *argv0 )
460 {
461 	extern GType vips_system_get_type( void );
462 	extern GType write_thread_state_get_type( void );
463 	extern GType sink_memory_thread_state_get_type( void );
464 	extern GType render_thread_state_get_type( void );
465 	extern GType vips_source_get_type( void );
466 	extern GType vips_source_custom_get_type( void );
467 	extern GType vips_target_get_type( void );
468 	extern GType vips_target_custom_get_type( void );
469 	extern GType vips_g_input_stream_get_type( void );
470 
471 	static gboolean started = FALSE;
472 	static gboolean done = FALSE;
473 	const char *vips_min_stack_size;
474 	const char *prefix;
475 	const char *libdir;
476 	char *locale;
477 
478 	/* Two stage done handling: 'done' means we've completed, 'started'
479 	 * means we're currently initialising. Use this to prevent recursive
480 	 * invocation.
481 	 */
482 	if( done )
483 		/* Called more than once, we succeeded, just return OK.
484 		 */
485 		return( 0 );
486 	if( started )
487 		/* Recursive invocation, something has broken horribly.
488 		 * Hopefully the first init will handle it.
489 		 */
490 		return( 0 );
491 	started = TRUE;
492 
493 	if( g_getenv( "VIPS_INFO" )
494 #if ENABLE_DEPRECATED
495 		|| g_getenv( "IM_INFO" )
496 #endif
497 	)
498 		vips_verbose();
499 	if( g_getenv( "VIPS_PROFILE" ) )
500 		vips_profile_set( TRUE );
501 	if( g_getenv( "VIPS_LEAK" ) )
502 		vips_leak_set( TRUE );
503 	if( g_getenv( "VIPS_TRACE" ) )
504 		vips_cache_set_trace( TRUE );
505 	if( g_getenv( "VIPS_PIPE_READ_LIMIT" ) )
506 		vips_pipe_read_limit =
507 			g_ascii_strtoll( g_getenv( "VIPS_PIPE_READ_LIMIT" ),
508 				NULL, 10 );
509 	vips_pipe_read_limit_set( vips_pipe_read_limit );
510 
511 #ifdef G_OS_WIN32
512 	/* Windows has a limit of 512 files open at once for the fopen() family
513 	 * of functions, and 2048 for the _open() family. This raises the limit
514 	 * of fopen() to the same level as _open().
515 	 *
516 	 * It will not go any higher than this, unfortunately.
517 	 */
518 	(void) _setmaxstdio( 2048 );
519 #endif /*G_OS_WIN32*/
520 
521 	vips__threadpool_init();
522 	vips__buffer_init();
523 	vips__meta_init();
524 
525 	/* This does an unsynchronised static hash table init on first call --
526 	 * we have to make sure we do this single-threaded. See:
527 	 * https://github.com/openslide/openslide/issues/161
528 	 */
529 #if !GLIB_CHECK_VERSION( 2, 48, 1 )
530 	(void) g_get_language_names();
531 #endif
532 
533 	if( !vips__global_lock )
534 		vips__global_lock = vips_g_mutex_new();
535 
536 	if( !vips__global_timer )
537 		vips__global_timer = g_timer_new();
538 
539 	VIPS_SETSTR( vips__argv0, argv0 );
540 	vips__prgname = g_path_get_basename( argv0 );
541 
542 	vips__thread_profile_attach( "main" );
543 
544 	/* We can't do VIPS_GATE_START() until command-line processing
545 	 * happens, since vips__thread_profile may not be set yet. Call
546 	 * directly.
547 	 */
548 	vips__thread_gate_start( "init: main" );
549 	vips__thread_gate_start( "init: startup" );
550 
551 	/* Try to discover our prefix.
552 	 */
553         if( (prefix = g_getenv( "VIPSHOME" )) )
554 		g_info( "VIPSHOME = %s", prefix );
555 	if( !(prefix = vips_guess_prefix( argv0, "VIPSHOME" )) ||
556 		!(libdir = vips_guess_libdir( argv0, "VIPSHOME" )) )
557 		return( -1 );
558 
559 	g_info( "VIPS_PREFIX = %s", VIPS_PREFIX );
560 	g_info( "VIPS_LIBDIR = %s", VIPS_LIBDIR );
561 	g_info( "prefix = %s", prefix );
562 	g_info( "libdir = %s", libdir );
563 
564 	/* Get i18n .mo files from $VIPSHOME/share/locale/.
565 	 */
566 	locale = g_build_filename( prefix, "share", "locale", NULL );
567 	bindtextdomain( GETTEXT_PACKAGE, locale );
568 	g_free( locale );
569 	bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
570 
571 	/* Register base vips types.
572 	 */
573 	(void) vips_image_get_type();
574 	(void) vips_region_get_type();
575 	(void) write_thread_state_get_type();
576 	(void) sink_memory_thread_state_get_type();
577 	(void) render_thread_state_get_type();
578 	(void) vips_source_get_type();
579 	(void) vips_source_custom_get_type();
580 	(void) vips_target_get_type();
581 	(void) vips_target_custom_get_type();
582 	vips__meta_init_types();
583 	vips__interpolate_init();
584 
585 #if ENABLE_DEPRECATED
586 	im__format_init();
587 #endif
588 
589 	/* Start up operator cache.
590 	 */
591 	vips__cache_init();
592 
593 	/* Recomp reordering system.
594 	 */
595 	vips__reorder_init();
596 
597 	/* Start up packages.
598 	 */
599 	(void) vips_system_get_type();
600 	vips_arithmetic_operation_init();
601 	vips_conversion_operation_init();
602 	vips_create_operation_init();
603 	vips_foreign_operation_init();
604 	vips_resample_operation_init();
605 	vips_colour_operation_init();
606 	vips_histogram_operation_init();
607 	vips_convolution_operation_init();
608 	vips_freqfilt_operation_init();
609 	vips_morphology_operation_init();
610 	vips_draw_operation_init();
611 	vips_mosaicing_operation_init();
612 	vips_g_input_stream_get_type();
613 
614 #ifdef ENABLE_MODULES
615 	/* Load any vips8 modules from the vips libdir. Keep going, even if
616 	 * some modules fail to load.
617 	 *
618 	 * Only do this if we have been built as a set of loadable
619 	 * modules, or we might try loading an operation into a library that
620 	 * already has that operation built in.
621 	 */
622 	(void) vips_load_plugins( "%s/vips-modules-%d.%d",
623 		libdir, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION );
624 #endif /*ENABLE_MODULES*/
625 
626 #if ENABLE_DEPRECATED
627 	/* Load any vips8 plugins from the vips libdir.
628 	 */
629 	(void) vips_load_plugins( "%s/vips-plugins-%d.%d",
630 		libdir, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION );
631 
632 	/* Load up any vips7 plugins in the vips libdir. We don't error on
633 	 * failure, it's too annoying to have VIPS refuse to start because of
634 	 * a broken plugin.
635 	 */
636 	if( im_load_plugins( "%s/vips-%d.%d",
637 		libdir, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION ) ) {
638 		g_warning( "%s", vips_error_buffer() );
639 		vips_error_clear();
640 	}
641 
642 	/* Also load from libdir. This is old and slightly broken behaviour
643 	 * :-( kept for back compat convenience.
644 	 */
645 	if( im_load_plugins( "%s", libdir ) ) {
646 		g_warning( "%s", vips_error_buffer() );
647 		vips_error_clear();
648 	}
649 #endif
650 
651 	/* Get the run-time compiler going.
652 	 */
653 	vips_vector_init();
654 
655 #ifdef HAVE_GSF
656 	/* Use this for structured file write.
657 	 */
658 	gsf_init();
659 #endif /*HAVE_GSF*/
660 
661 #ifdef HAVE_ATEXIT
662 	atexit( vips__atexit );
663 #endif /*HAVE_ATEXIT*/
664 
665 #ifdef DEBUG_LEAK
666 	vips__image_pixels_quark =
667 		g_quark_from_static_string( "vips-image-pixels" );
668 #endif /*DEBUG_LEAK*/
669 
670 	done = TRUE;
671 
672 	/* If VIPS_WARNING is defined, suppress all warning messages from vips.
673 	 *
674 	 * Libraries should not call g_log_set_handler(), it is
675 	 * supposed to be for the application layer, but this can be awkward to
676 	 * set up if you are using libvips from something like Ruby. Allow this
677 	 * env var hack as a workaround.
678 	 */
679 	if( g_getenv( "VIPS_WARNING" )
680 #if ENABLE_DEPRECATED
681 		|| g_getenv( "IM_WARNING" )
682 #endif
683 	)
684 		g_log_set_handler( G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
685 			empty_log_handler, NULL );
686 
687 	/* Set a minimum stacksize, if we can.
688 	 */
689         if( (vips_min_stack_size = g_getenv( "VIPS_MIN_STACK_SIZE" )) )
690 		(void) set_stacksize( vips__parse_size( vips_min_stack_size ) );
691 
692 	vips__thread_gate_stop( "init: startup" );
693 
694 	return( 0 );
695 }
696 
697 /* Call this before vips stuff that uses stuff we need to have inited.
698  */
699 void
vips_check_init(void)700 vips_check_init( void )
701 {
702 	/* Pass in a nonsense name for argv0 ... this init path is only here
703 	 * for old programs which are missing an vips_init() call. We need
704 	 * i18n set up before we can translate.
705 	 */
706 	if( vips_init( "vips" ) )
707 		vips_error_clear();
708 }
709 
710 /**
711  * vips_thread_shutdown:
712  *
713  * Free any thread-private data and flush any profiling information.
714  *
715  * This function needs to be called when a thread that has been using vips
716  * exits. It is called for you by vips_shutdown() and for any threads created
717  * within the #VipsThreadPool.
718  *
719  * You will need to call it from threads created in
720  * other ways or there will be memory leaks. If you do not call it, vips
721  * will generate a warning message.
722  *
723  * It may be called many times, and you can continue using vips after
724  * calling it. Calling it too often will reduce performance.
725  */
726 void
vips_thread_shutdown(void)727 vips_thread_shutdown( void )
728 {
729 	vips__thread_profile_detach();
730 	vips__buffer_shutdown();
731 }
732 
733 /**
734  * vips_shutdown:
735  *
736  * Call this to drop caches, close plugins, terminate background threads, and
737  * finalize any internal library testing.
738  *
739  * vips_shutdown() is optional. If you don't call it, your platform will
740  * clean up for you. The only negative consequences are that the leak checker
741  * and the profiler will not work.
742  *
743  * You may call VIPS_INIT() many times and vips_shutdown() many times, but you
744  * must not call VIPS_INIT() after vips_shutdown(). In other words, you cannot
745  * stop and restart libvips.
746  *
747  * See also: vips_profile_set(), vips_leak_set().
748  */
749 void
vips_shutdown(void)750 vips_shutdown( void )
751 {
752 #ifdef DEBUG
753 	printf( "vips_shutdown:\n" );
754 #endif /*DEBUG*/
755 
756 	vips_cache_drop_all();
757 
758 #if ENABLE_DEPRECATED
759 	im_close_plugins();
760 #endif
761 
762 	/* Mustn't run this more than once. Don't use the VIPS_GATE macro,
763 	 * since we don't for gate start.
764 	 */
765 {
766 	static gboolean done = FALSE;
767 
768 	if( !done )
769 		vips__thread_gate_stop( "init: main" );
770 }
771 
772 	vips__render_shutdown();
773 	vips_thread_shutdown();
774 	vips__thread_profile_stop();
775 	vips__threadpool_shutdown();
776 
777 #ifdef HAVE_GSF
778 	gsf_shutdown();
779 #endif /*HAVE_GSF*/
780 
781 	/* Don't free vips__global_lock -- we want to be able to use
782 	 * vips_error_buffer() after vips_shutdown(), since vips_leak() can
783 	 * call it.
784 	 */
785 	VIPS_FREE( vips__argv0 );
786 	VIPS_FREE( vips__prgname );
787 	VIPS_FREEF( g_timer_destroy, vips__global_timer );
788 }
789 
790 const char *
vips__gettext(const char * msgid)791 vips__gettext( const char *msgid )
792 {
793 	vips_check_init();
794 
795 	return( dgettext( GETTEXT_PACKAGE, msgid ) );
796 }
797 
798 const char *
vips__ngettext(const char * msgid,const char * plural,unsigned long int n)799 vips__ngettext( const char *msgid, const char *plural, unsigned long int n )
800 {
801 	vips_check_init();
802 
803 	return( dngettext( GETTEXT_PACKAGE, msgid, plural, n ) );
804 }
805 
806 static gboolean
vips_lib_info_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)807 vips_lib_info_cb( const gchar *option_name, const gchar *value,
808 	gpointer data, GError **error )
809 {
810 	vips_verbose();
811 
812 	return( TRUE );
813 }
814 
815 static gboolean
vips_set_fatal_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)816 vips_set_fatal_cb( const gchar *option_name, const gchar *value,
817 	gpointer data, GError **error )
818 {
819 	vips__fatal = 1;
820 
821 	/* Set masks for debugging ... stop on any problem.
822 	 */
823 	g_log_set_always_fatal(
824 		G_LOG_FLAG_RECURSION |
825 		G_LOG_FLAG_FATAL |
826 		G_LOG_LEVEL_ERROR |
827 		G_LOG_LEVEL_CRITICAL |
828 		G_LOG_LEVEL_WARNING );
829 
830 	return( TRUE );
831 }
832 
833 static gboolean
vips_lib_version_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)834 vips_lib_version_cb( const gchar *option_name, const gchar *value,
835 	gpointer data, GError **error )
836 {
837 	printf( "libvips %s\n", VIPS_VERSION_STRING );
838 	vips_shutdown();
839 	exit( 0 );
840 }
841 
842 static gboolean
vips_lib_config_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)843 vips_lib_config_cb( const gchar *option_name, const gchar *value,
844 	gpointer data, GError **error )
845 {
846 	char **split;
847 	char *config;
848 
849 	split = g_strsplit( VIPS_CONFIG, ", ", -1 );
850 	config = g_strjoinv( "\n", split );
851 
852 	printf( "%s\n", config );
853 	g_strfreev( split );
854 	g_free( config );
855 
856 	vips_shutdown();
857 	exit( 0 );
858 }
859 
860 static gboolean
vips_cache_max_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)861 vips_cache_max_cb( const gchar *option_name, const gchar *value,
862 	gpointer data, GError **error )
863 {
864 	vips_cache_set_max( vips__parse_size( value ) );
865 
866 	return( TRUE );
867 }
868 
869 static gboolean
vips_cache_max_memory_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)870 vips_cache_max_memory_cb( const gchar *option_name, const gchar *value,
871 	gpointer data, GError **error )
872 {
873 	vips_cache_set_max_mem( vips__parse_size( value ) );
874 
875 	return( TRUE );
876 }
877 
878 static gboolean
vips_cache_max_files_cb(const gchar * option_name,const gchar * value,gpointer data,GError ** error)879 vips_cache_max_files_cb( const gchar *option_name, const gchar *value,
880 	gpointer data, GError **error )
881 {
882 	vips_cache_set_max_files( vips__parse_size( value ) );
883 
884 	return( TRUE );
885 }
886 
887 static GOptionEntry option_entries[] = {
888 	{ "vips-info", 0, G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
889 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_lib_info_cb,
890 		N_( "show informative messages" ), NULL },
891 	{ "vips-fatal", 0, G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
892 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_set_fatal_cb,
893 		N_( "abort on first error or warning" ), NULL },
894 	{ "vips-concurrency", 0, 0,
895 		G_OPTION_ARG_INT, &vips__concurrency,
896 		N_( "evaluate with N concurrent threads" ), "N" },
897 	{ "vips-tile-width", 0, G_OPTION_FLAG_HIDDEN,
898 		G_OPTION_ARG_INT, &vips__tile_width,
899 		N_( "set tile width to N (DEBUG)" ), "N" },
900 	{ "vips-tile-height", 0, G_OPTION_FLAG_HIDDEN,
901 		G_OPTION_ARG_INT, &vips__tile_height,
902 		N_( "set tile height to N (DEBUG)" ), "N" },
903 	{ "vips-thinstrip-height", 0, G_OPTION_FLAG_HIDDEN,
904 		G_OPTION_ARG_INT, &vips__thinstrip_height,
905 		N_( "set thinstrip height to N (DEBUG)" ), "N" },
906 	{ "vips-fatstrip-height", 0, G_OPTION_FLAG_HIDDEN,
907 		G_OPTION_ARG_INT, &vips__fatstrip_height,
908 		N_( "set fatstrip height to N (DEBUG)" ), "N" },
909 	{ "vips-progress", 0, 0,
910 		G_OPTION_ARG_NONE, &vips__progress,
911 		N_( "show progress feedback" ), NULL },
912 	{ "vips-leak", 0, 0,
913 		G_OPTION_ARG_NONE, &vips__leak,
914 		N_( "leak-check on exit" ), NULL },
915 	{ "vips-profile", 0, 0,
916 		G_OPTION_ARG_NONE, &vips__thread_profile,
917 		N_( "profile and dump timing on exit" ), NULL },
918 	{ "vips-disc-threshold", 0, 0,
919 		G_OPTION_ARG_STRING, &vips__disc_threshold,
920 		N_( "images larger than N are decompressed to disc" ), "N" },
921 	{ "vips-novector", 0, G_OPTION_FLAG_REVERSE,
922 		G_OPTION_ARG_NONE, &vips__vector_enabled,
923 		N_( "disable vectorised versions of operations" ), NULL },
924 	{ "vips-cache-max", 0, 0,
925 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_cache_max_cb,
926 		N_( "cache at most N operations" ), "N" },
927 	{ "vips-cache-max-memory", 0, 0,
928 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_cache_max_memory_cb,
929 		N_( "cache at most N bytes in memory" ), "N" },
930 	{ "vips-cache-max-files", 0, 0,
931 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_cache_max_files_cb,
932 		N_( "allow at most N open files" ), "N" },
933 	{ "vips-cache-trace", 0, 0,
934 		G_OPTION_ARG_NONE, &vips__cache_trace,
935 		N_( "trace operation cache" ), NULL },
936 	{ "vips-cache-dump", 0, 0,
937 		G_OPTION_ARG_NONE, &vips__cache_dump,
938 		N_( "dump operation cache on exit" ), NULL },
939 	{ "vips-version", 0, G_OPTION_FLAG_NO_ARG,
940 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_lib_version_cb,
941 		N_( "print libvips version" ), NULL },
942 	{ "vips-config", 0, G_OPTION_FLAG_NO_ARG,
943 		G_OPTION_ARG_CALLBACK, (gpointer) &vips_lib_config_cb,
944 		N_( "print libvips config" ), NULL },
945 	{ "vips-pipe-read-limit", 0, 0,
946 		G_OPTION_ARG_INT64, (gpointer) &vips_pipe_read_limit,
947 		N_( "read at most this many bytes from a pipe" ), NULL },
948 	{ NULL }
949 };
950 
951 /**
952  * vips_add_option_entries:
953  * @option_group: group to add to
954  *
955  * Add the standard vips %GOptionEntry to a %GOptionGroup.
956  *
957  * See also: g_option_group_new().
958  */
959 void
vips_add_option_entries(GOptionGroup * option_group)960 vips_add_option_entries( GOptionGroup *option_group )
961 {
962 	g_option_group_add_entries( option_group, option_entries );
963 }
964 
965 /* Find the prefix part of a dir ... name is the name of this prog from argv0.
966  *
967  * dir					name		guess prefix
968  *
969  * /home/john/vips-7.6.4/bin/vips-7.6	vips-7.6	/home/john/vips-7.6.4
970  * /usr/local/bin/ip			ip		/usr/local
971  *
972  * all other forms ... return NULL.
973  */
974 static char *
extract_prefix(const char * dir,const char * name)975 extract_prefix( const char *dir, const char *name )
976 {
977 	char edir[VIPS_PATH_MAX];
978 	char vname[VIPS_PATH_MAX];
979 	int i;
980 
981 	g_info( "trying for dir = \"%s\", name = \"%s\"", dir, name );
982 
983 	/* Is dir relative? Prefix with cwd.
984 	 */
985 	if( !g_path_is_absolute( dir ) ) {
986 		char *cwd;
987 
988 		cwd = g_get_current_dir();
989 		vips_snprintf( edir, VIPS_PATH_MAX,
990 			"%s" G_DIR_SEPARATOR_S "%s", cwd, dir );
991 		g_free( cwd );
992 	}
993 	else {
994 		vips_strncpy( edir, dir, VIPS_PATH_MAX );
995 	}
996 
997 	/* Chop off the trailing prog name, plus the trailing
998 	 * G_DIR_SEPARATOR_S.
999 	 */
1000 	if( !vips_ispostfix( edir, name ) )
1001 		return( NULL );
1002 	vips_strncpy( vname, edir, VIPS_PATH_MAX );
1003 	vname[strlen( edir ) - strlen( name ) - 1] = '\0';
1004 
1005 	/* Remove any "/./", any trailing "/.", any trailing "/".
1006 	 */
1007 	for( i = 0; i < (int) strlen( vname ); i++ )
1008 		if( vips_isprefix( G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S,
1009 			vname + i ) )
1010 			memmove( vname + i, vname + i + 2,
1011 				strlen( vname + i + 2 ) + 1 );
1012 	if( vips_ispostfix( vname, G_DIR_SEPARATOR_S "." ) )
1013 		vname[strlen( vname ) - 2] = '\0';
1014 	if( vips_ispostfix( vname, G_DIR_SEPARATOR_S ) )
1015 		vname[strlen( vname ) - 1] = '\0';
1016 
1017 	g_info( "canonicalised path = \"%s\"", vname );
1018 
1019 	/* Ought to be a "/bin" at the end now.
1020 	 */
1021 	if( !vips_ispostfix( vname, G_DIR_SEPARATOR_S "bin" ) )
1022 		return( NULL );
1023 	vname[strlen( vname ) - strlen( G_DIR_SEPARATOR_S "bin" )] = '\0';
1024 
1025 	g_info( "found \"%s\"", vname );
1026 
1027 	return( vips_strdup( NULL, vname ) );
1028 }
1029 
1030 /* Search a path for a file ... we overwrite the PATH string passed in.
1031  */
1032 static char *
scan_path(char * path,const char * name)1033 scan_path( char *path, const char *name )
1034 {
1035 	char *p, *q;
1036 	char *prefix;
1037 
1038 	for( p = path;
1039 		(q = vips_break_token( p, G_SEARCHPATH_SEPARATOR_S )); p = q ) {
1040 		char str[VIPS_PATH_MAX];
1041 
1042 		/* Form complete path.
1043 		 */
1044 		vips_snprintf( str, VIPS_PATH_MAX,
1045 			"%s" G_DIR_SEPARATOR_S "%s", p, name );
1046 
1047 		g_info( "looking in \"%s\" for \"%s\"",
1048 			p, name );
1049 
1050 		if( vips_existsf( "%s", str ) &&
1051 			(prefix = extract_prefix( str, name )) ) {
1052 			return( prefix );
1053 		}
1054 	}
1055 
1056 	return( NULL );
1057 }
1058 
1059 /* Look for a file along PATH. If we find it, look for an enclosing prefix.
1060  */
1061 static char *
find_file(const char * name)1062 find_file( const char *name )
1063 {
1064 	const char *path = g_getenv( "PATH" );
1065 	char *prefix;
1066 	char full_path[VIPS_PATH_MAX];
1067 
1068 	if( !path )
1069 		return( NULL );
1070 
1071 	g_info( "g_getenv( \"PATH\" ) == \"%s\"", path );
1072 
1073 #ifdef G_OS_WIN32
1074 {
1075 	char *dir;
1076 
1077 	/* Windows always searches '.' first, so prepend cwd to path.
1078 	 */
1079 	dir = g_get_current_dir();
1080 	vips_snprintf( full_path, VIPS_PATH_MAX,
1081 		"%s" G_SEARCHPATH_SEPARATOR_S "%s", dir, path );
1082 	g_free( dir );
1083 }
1084 #else /*!G_OS_WIN32*/
1085 	vips_strncpy( full_path, path, VIPS_PATH_MAX );
1086 #endif /*G_OS_WIN32*/
1087 
1088 	if( (prefix = scan_path( full_path, name )) )
1089 		return( prefix );
1090 
1091 	return( NULL );
1092 }
1093 
1094 /* Guess a value for the install PREFIX.
1095  */
1096 static const char *
guess_prefix(const char * argv0,const char * name)1097 guess_prefix( const char *argv0, const char *name )
1098 {
1099 	char *prefix;
1100 
1101 	/* We've already checked for VIPSHOME. If the configure-time
1102 	 * library prefix looks OK, use the configure-time prefix.
1103 	 */
1104 	if( vips_existsf( "%s/vips-modules-%d.%d",
1105 		VIPS_LIBDIR, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION ) ) {
1106 		g_info( "found %s/vips-modules-%d.%d",
1107 			VIPS_LIBDIR, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION );
1108 		g_info( "using configure-time prefix" );
1109 		return( VIPS_PREFIX );
1110 	}
1111 
1112 	/* Try to guess from argv0.
1113 	 */
1114 	if( argv0 ) {
1115 		if( g_path_is_absolute( argv0 ) ) {
1116 			/* Must point to our executable.
1117 			 */
1118 			if( (prefix = extract_prefix( argv0, name )) ) {
1119 				g_info( "found \"%s\" from argv0", prefix );
1120 				return( prefix );
1121 			}
1122 		}
1123 
1124 		/* Look along path for name.
1125 		 */
1126 		if( (prefix = find_file( name )) ) {
1127 			g_info( "found \"%s\" from PATH", prefix );
1128 			return( prefix );
1129 		}
1130         }
1131 
1132 	/* Try to guess from cwd. Only if this is a relative path, though.
1133 	 */
1134 	if( argv0 &&
1135 		!g_path_is_absolute( argv0 ) ) {
1136 		char *dir;
1137 		char full_path[VIPS_PATH_MAX];
1138 		char *resolved;
1139 
1140 		dir = g_get_current_dir();
1141 		vips_snprintf( full_path, VIPS_PATH_MAX,
1142 			"%s" G_DIR_SEPARATOR_S "%s", dir, argv0 );
1143 		g_free( dir );
1144 
1145 		if( (resolved = vips_realpath( full_path )) ) {
1146 			prefix = extract_prefix( resolved, name );
1147 			g_free( resolved );
1148 
1149 			if( prefix ) {
1150 				g_info( "found \"%s\" from cwd", prefix );
1151 				return( prefix );
1152 			}
1153 		}
1154 	}
1155 
1156 	/* Fall back to the configure-time prefix.
1157 	 */
1158 	return( VIPS_PREFIX );
1159 }
1160 
1161 /**
1162  * vips_guess_prefix:
1163  * @argv0: program name (typically argv[0])
1164  * @env_name: save prefix in this environment variable
1165  *
1166  * vips_guess_prefix() tries to guess the install directory. You should pass
1167  * in the value of argv[0] (the name your program was run as) as a clue to
1168  * help it out, plus the name of the environment variable you let the user
1169  * override your package install area with (eg. "VIPSHOME").
1170  *
1171  * On success, vips_guess_prefix() returns the prefix it discovered, and as a
1172  * side effect, sets the environment variable (if it's not set).
1173  *
1174  * Don't free the return string!
1175  *
1176  * See also: vips_guess_libdir().
1177  *
1178  * Returns: (transfer none): the install prefix as a static string, do not free.
1179  */
1180 const char *
vips_guess_prefix(const char * argv0,const char * env_name)1181 vips_guess_prefix( const char *argv0, const char *env_name )
1182 {
1183         const char *prefix;
1184 
1185 	/* Already set?
1186 	 */
1187 	if( (prefix = g_getenv( env_name )) )
1188                 return( prefix );
1189 
1190 #ifdef G_OS_WIN32
1191 	prefix = vips__windows_prefix();
1192 #else /*!G_OS_WIN32*/
1193 {
1194         char *basename;
1195 
1196 	basename = g_path_get_basename( argv0 );
1197 	prefix = guess_prefix( argv0, basename );
1198 	g_free( basename );
1199 }
1200 #endif /*G_OS_WIN32*/
1201 
1202 	g_setenv( env_name, prefix, TRUE );
1203 
1204 	return( prefix );
1205 }
1206 
1207 /**
1208  * vips_guess_libdir:
1209  * @argv0: program name (typically argv[0])
1210  * @env_name: save prefix in this environment variable
1211  *
1212  * vips_guess_libdir() tries to guess the install directory (usually the
1213  * configure libdir, or $prefix/lib). You should pass
1214  * in the value of argv[0] (the name your program was run as) as a clue to
1215  * help it out, plus the name of the environment variable you let the user
1216  * override your package install area with (eg. "VIPSHOME").
1217  *
1218  * On success, vips_guess_libdir() returns the libdir it discovered, and as a
1219  * side effect, sets the prefix environment variable (if it's not set).
1220  *
1221  * Don't free the return string!
1222  *
1223  * See also: vips_guess_prefix().
1224  *
1225  * Returns: (transfer none): the libdir as a static string, do not free.
1226  */
1227 const char *
vips_guess_libdir(const char * argv0,const char * env_name)1228 vips_guess_libdir( const char *argv0, const char *env_name )
1229 {
1230 	const char *prefix = vips_guess_prefix( argv0, env_name );
1231 	static char *libdir = NULL;
1232 
1233 	char *suffix;
1234 
1235 	if( libdir )
1236 		return( libdir );
1237 
1238 	/* Have we been moved since configure? If not, use the configure-time
1239 	 * libdir.
1240 	 *
1241 	 * The lib directory name can be eg. "lib", "lib64" etc. depending on
1242 	 * the platform, so copy that from the configure-time libdir if we can.
1243 	 * The configure-time LIBDIR is generated by autotools and always uses
1244 	 * '/', even on Windows.
1245 	 */
1246 	if( strcmp( prefix, VIPS_PREFIX ) == 0 )
1247 		libdir = VIPS_LIBDIR;
1248 	else if( (suffix = strrchr( VIPS_LIBDIR, '/' )) )
1249 		libdir = g_strdup_printf( "%s%s", prefix, suffix );
1250 	else
1251 		libdir = g_strdup_printf( "%s/lib", prefix );
1252 
1253 	return( libdir );
1254 }
1255 
1256 /**
1257  * vips_version_string:
1258  *
1259  * Get the VIPS version as a static string, including a build date and time.
1260  * Do not free.
1261  *
1262  * Returns: (transfer none): a static version string
1263  */
1264 const char *
vips_version_string(void)1265 vips_version_string( void )
1266 {
1267 	return( VIPS_VERSION_STRING );
1268 }
1269 
1270 /**
1271  * vips_version:
1272  * @flag: which field of the version to get
1273  *
1274  * Get the major, minor or micro library version, with @flag values 0, 1 and
1275  * 2.
1276  *
1277  * Get the ABI current, revision and age (as used by libtool) with @flag
1278  * values 3, 4, 5.
1279  *
1280  * Returns: library version number
1281  */
1282 int
vips_version(int flag)1283 vips_version( int flag )
1284 {
1285 	switch( flag ) {
1286 	case 0:
1287 		return( VIPS_MAJOR_VERSION );
1288 
1289 	case 1:
1290 		return( VIPS_MINOR_VERSION );
1291 
1292 	case 2:
1293 		return( VIPS_MICRO_VERSION );
1294 
1295 	case 3:
1296 		return( VIPS_LIBRARY_CURRENT );
1297 
1298 	case 4:
1299 		return( VIPS_LIBRARY_REVISION );
1300 
1301 	case 5:
1302 		return( VIPS_LIBRARY_AGE );
1303 
1304 	default:
1305 		vips_error( "vips_version", "%s", _( "flag not in [0, 5]" ) );
1306 		return( -1 );
1307 	}
1308 }
1309 
1310 /**
1311  * vips_leak_set:
1312  * @leak: turn leak checking on or off
1313  *
1314  * Turn on or off vips leak checking. See also --vips-leak,
1315  * vips_add_option_entries() and the `VIPS_LEAK` environment variable.
1316  *
1317  * You should call this very early in your program.
1318  */
1319 void
vips_leak_set(gboolean leak)1320 vips_leak_set( gboolean leak )
1321 {
1322 	vips__leak = leak;
1323 }
1324 
1325 /* Deprecated.
1326  */
1327 size_t
vips__get_sizeof_vipsobject(void)1328 vips__get_sizeof_vipsobject( void )
1329 {
1330 	return( sizeof( VipsObject ) );
1331 }
1332 
1333