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