1 /* base class for all vips operations
2  *
3  * 30/12/14
4  * 	- display default/min/max for pspec in usage
5  */
6 
7 /*
8 
9     Copyright (C) 1991-2005 The National Gallery
10 
11     This library is free software; you can redistribute it and/or
12     modify it under the terms of the GNU Lesser General Public
13     License as published by the Free Software Foundation; either
14     version 2.1 of the License, or (at your option) any later version.
15 
16     This library is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     Lesser General Public License for more details.
20 
21     You should have received a copy of the GNU Lesser General Public
22     License along with this library; if not, write to the Free Software
23     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24     02110-1301  USA
25 
26  */
27 
28 /*
29 
30     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
31 
32  */
33 
34 /*
35 #define VIPS_DEBUG
36  */
37 
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif /*HAVE_CONFIG_H*/
41 #include <vips/intl.h>
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <math.h>
47 
48 #include <vips/vips.h>
49 #include <vips/internal.h>
50 #include <vips/debug.h>
51 
52 #include <gobject/gvaluecollector.h>
53 
54 /**
55  * SECTION: operation
56  * @short_description: the VIPS operation base object class
57  * @stability: Stable
58  * @see_also: <link linkend="VipsObject">object</link>
59  * @include: vips/vips.h
60  *
61  * The #VipsOperation class and associated types and macros.
62  *
63  * #VipsOperation is the base class for all operations in libvips. It builds
64  * on #VipsObject to provide the introspection and command-line interface to
65  * libvips.
66  *
67  * It also maintains a cache of recent operations. See below.
68  *
69  * vips_call(), vips_call_split() and vips_call_split_option_string() are used
70  * by vips to implement the C API. They can execute any #VipsOperation,
71  * passing in a set of required and optional arguments. Normally you would not
72  * use these functions directly: every operation has a tiny wrapper function
73  * which provides type-safety for the required arguments. For example,
74  * vips_embed() is defined as:
75  *
76  * |[
77  * int
78  * vips_embed( VipsImage *in, VipsImage **out,
79  *   int x, int y, int width, int height, ... )
80  * {
81  *   va_list ap;
82  *   int result;
83  *
84  *   va_start( ap, height );
85  *   result = vips_call_split( "embed", ap, in, out, x, y, width, height );
86  *   va_end( ap );
87  *
88  *   return( result );
89  * }
90  * ]|
91  *
92  * Use vips_call_argv() to run any vips operation from a command-line style
93  * argc/argv array. This is the thing used by the vips main program to
94  * implement the vips command-line interface.
95  *
96  * ## #VipsOperation and reference counting
97  *
98  * After calling a #VipsOperation you are responsible for unreffing any output
99  * objects. For example, consider:
100  *
101  * |[
102  * VipsImage *im = ...;
103  * VipsImage *t1;
104  *
105  * if (vips_invert (im, &t1, NULL))
106  *   error ..
107  * ]|
108  *
109  * This will invert @im and return a new #VipsImage, @t1. As the caller
110  * of vips_invert(), you are responsible for @t1 and must unref it when you no
111  * longer need it. If vips_invert() fails, no @t1 is returned and you don't
112  * need to do anything.
113  *
114  * If you don't need to use @im for another operation,
115  * you can unref @im immediately after the call. If @im is needed to calculate
116  * @t1, vips_invert() will add a ref to @im and automatically drop it when @t1
117  * is unreffed.
118  *
119  * Consider running two operations, one after the other. You could write:
120  *
121  * |[
122  * VipsImage *im = ...;
123  * VipsImage *t1, *t2;
124  *
125  * if (vips_invert (im, &t1, NULL)) {
126  *   g_object_unref (im);
127  *   return -1;
128  * }
129  * g_object_unref (im);
130  *
131  * if (vips_flip (t1, &t2, VIPS_DIRECTION_HORIZONTAL, NULL)) {
132  *   g_object_unref (t1);
133  *   return -1;
134  * }
135  * g_object_unref (t1);
136  * ]|
137  *
138  * This is correct, but rather long-winded. libvips provides a handy thing to
139  * make a vector of auto-freeing object references. You can write this as:
140  *
141  * |[
142  * VipsObject *parent = ...;
143  * VipsImage *im = ...;
144  * VipsImage *t = (VipsImage **) vips_object_local_array (parent, 2);
145  *
146  * if (vips_invert (im, &t[0], NULL) ||
147  *   vips_flip (t[0], &t[1], VIPS_DIRECTION_HORIZONTAL, NULL))
148  *   return -1;
149  * ]|
150  *
151  * where @parent is some enclosing object which will be unreffed when this
152  * task is complete. vips_object_local_array() makes an array of #VipsObject
153  * (or #VipsImage, in this case) where when @parent is freed, all non-NULL
154  * #VipsObject in the array are also unreffed.
155  *
156  * ## The #VipsOperation cache
157  *
158  * Because all #VipsObject are immutable, they can be cached. The cache is
159  * very simple to use: instead of calling vips_object_build(), call
160  * vips_cache_operation_build(). This function calculates a hash from the
161  * operations's input arguments and looks it up in table of all recent
162  * operations. If there's a hit, the new operation is unreffed, the old
163  * operation reffed, and the old operation returned in place of the new one.
164  *
165  * The cache size is controlled with vips_cache_set_max() and friends.
166  */
167 
168 /**
169  * VipsOperationFlags:
170  * @VIPS_OPERATION_NONE: no flags
171  * @VIPS_OPERATION_SEQUENTIAL: can work sequentially with a small buffer
172  * @VIPS_OPERATION_NOCACHE: must not be cached
173  * @VIPS_OPERATION_DEPRECATED: a compatibility thing
174  *
175  * Flags we associate with an operation.
176  *
177  * @VIPS_OPERATION_SEQUENTIAL means that the operation works like vips_conv():
178  * it can process images top-to-bottom with only small non-local
179  * references.
180  *
181  * Every scan-line must be requested, you are not allowed to skip
182  * ahead, but as a special case, the very first request can be for a region
183  * not at the top of the image. In this case, the first part of the image will
184  * be read and discarded
185  *
186  * Every scan-line must be requested, you are not allowed to skip
187  * ahead, but as a special case, the very first request can be for a region
188  * not at the top of the image. In this case, the first part of the image will
189  * be read and discarded
190  *
191  * @VIPS_OPERATION_NOCACHE means that the operation must not be cached by
192  * vips.
193  *
194  * @VIPS_OPERATION_DEPRECATED means this is an old operation kept in vips for
195  * compatibility only and should be hidden from users.
196  */
197 
198 /* Abstract base class for operations.
199  */
200 
201 /* Our signals.
202  */
203 enum {
204 	SIG_INVALIDATE,
205 	SIG_LAST
206 };
207 
208 static guint vips_operation_signals[SIG_LAST] = { 0 };
209 
210 G_DEFINE_ABSTRACT_TYPE( VipsOperation, vips_operation, VIPS_TYPE_OBJECT );
211 
212 static void
vips_operation_finalize(GObject * gobject)213 vips_operation_finalize( GObject *gobject )
214 {
215 	VipsOperation *operation = VIPS_OPERATION( gobject );
216 
217 	VIPS_DEBUG_MSG( "vips_operation_finalize: %p\n", gobject );
218 
219 	if( operation->pixels )
220 		g_info( _( "%d pixels calculated" ), operation->pixels );
221 
222 	G_OBJECT_CLASS( vips_operation_parent_class )->finalize( gobject );
223 }
224 
225 static void
vips_operation_dispose(GObject * gobject)226 vips_operation_dispose( GObject *gobject )
227 {
228 	VIPS_DEBUG_MSG( "vips_operation_dispose: %p\n", gobject );
229 
230 	G_OBJECT_CLASS( vips_operation_parent_class )->dispose( gobject );
231 }
232 
233 /* Three basic types of command-line argument.
234  *
235  * INPUTS: things like an input image, there is a filename argument on the
236  * command-line which is used to construct the operation argument.
237  *
238  * NOARG_OUTPUT: things like the result of VipsMax, there's no correspondiong
239  * command-line argument, we just print the value.
240  *
241  * OPTIONS: optional arguments.
242  *
243  * NONE: hide this thing.
244  */
245 
246 typedef enum {
247 	USAGE_INPUTS,
248 	USAGE_NOARG_OUTPUT,
249 	USAGE_OPTIONS,
250 	USAGE_NONE
251 } UsageType;
252 
253 typedef struct {
254 	char *message;		/* header message on first print */
255 	UsageType type; 	/* Type of arg to select */
256 	gboolean oftype;	/* Show as "of type" */
257 	int n;			/* Arg number */
258 } VipsOperationClassUsage;
259 
260 /* Put an arg into one the categories above.
261  */
262 static UsageType
vips_operation_class_usage_classify(VipsArgumentClass * argument_class)263 vips_operation_class_usage_classify( VipsArgumentClass *argument_class )
264 {
265 	if( !(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ||
266 		(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) )
267 		return( USAGE_NONE );
268 
269 	if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) )
270 		return( USAGE_OPTIONS );
271 
272 	if( vips_argument_class_needsstring( argument_class ) )
273 		return( USAGE_INPUTS );
274 
275 	if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) &&
276 		!vips_argument_class_needsstring( argument_class ) )
277 		return( USAGE_NOARG_OUTPUT );
278 
279 	return( USAGE_NONE );
280 }
281 
282 static void
vips_operation_pspec_usage(VipsBuf * buf,GParamSpec * pspec)283 vips_operation_pspec_usage( VipsBuf *buf, GParamSpec *pspec )
284 {
285 	GType type = G_PARAM_SPEC_VALUE_TYPE( pspec );
286 
287 	/* These are the pspecs that vips uses that have interesting values.
288 	 */
289 	if( G_IS_PARAM_SPEC_ENUM( pspec ) ) {
290 		GTypeClass *class = g_type_class_ref( type );
291 		GParamSpecEnum *pspec_enum = (GParamSpecEnum *) pspec;
292 
293 		GEnumClass *genum;
294 		int i;
295 
296 		/* Should be impossible, no need to warn.
297 		 */
298 		if( !class )
299 			return;
300 
301 		genum = G_ENUM_CLASS( class );
302 
303 		vips_buf_appendf( buf, "\t\t\t" );
304 		vips_buf_appendf( buf, "%s", _( "default" ) );
305 		vips_buf_appendf( buf, ": %s\n",
306 			vips_enum_nick( type, pspec_enum->default_value ) );
307 		vips_buf_appendf( buf, "\t\t\t" );
308 		vips_buf_appendf( buf, "%s", _( "allowed" ) );
309 		vips_buf_appendf( buf, ": " );
310 
311 		/* -1 since we always have a "last" member.
312 		 */
313 		for( i = 0; i < genum->n_values - 1; i++ ) {
314 			if( i > 0 )
315 				vips_buf_appends( buf, ", " );
316 			vips_buf_appends( buf, genum->values[i].value_nick );
317 		}
318 
319 		vips_buf_appendf( buf, "\n" );
320 	}
321 	else if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) ) {
322 		GParamSpecBoolean *pspec_boolean = (GParamSpecBoolean *) pspec;
323 
324 		vips_buf_appendf( buf, "\t\t\t" );
325 		vips_buf_appendf( buf, "%s", _( "default" ) );
326 		vips_buf_appendf( buf, ": %s\n",
327 			pspec_boolean->default_value ? "true" : "false" );
328 	}
329 	else if( G_IS_PARAM_SPEC_DOUBLE( pspec ) ) {
330 		GParamSpecDouble *pspec_double = (GParamSpecDouble *) pspec;
331 
332 		vips_buf_appendf( buf, "\t\t\t" );
333 		vips_buf_appendf( buf, "%s", _( "default" ) );
334 		vips_buf_appendf( buf, ": %g\n", pspec_double->default_value );
335 		vips_buf_appendf( buf, "\t\t\t" );
336 		vips_buf_appendf( buf, "%s", _( "min" ) );
337 		vips_buf_appendf( buf, ": %g, ", pspec_double->minimum );
338 		vips_buf_appendf( buf, "%s", _( "max" ) );
339 		vips_buf_appendf( buf, ": %g\n", pspec_double->maximum );
340 	}
341 	else if( G_IS_PARAM_SPEC_INT( pspec ) ) {
342 		GParamSpecInt *pspec_int = (GParamSpecInt *) pspec;
343 
344 		vips_buf_appendf( buf, "\t\t\t" );
345 		vips_buf_appendf( buf, "%s", _( "default" ) );
346 		vips_buf_appendf( buf, ": %d\n", pspec_int->default_value );
347 		vips_buf_appendf( buf, "\t\t\t" );
348 		vips_buf_appendf( buf, "%s", _( "min" ) );
349 		vips_buf_appendf( buf, ": %d, ", pspec_int->minimum );
350 		vips_buf_appendf( buf, "%s", _( "max" ) );
351 		vips_buf_appendf( buf, ": %d\n", pspec_int->maximum );
352 	}
353 
354 }
355 
356 static void *
vips_operation_class_usage_arg(VipsObjectClass * object_class,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsBuf * buf,VipsOperationClassUsage * usage)357 vips_operation_class_usage_arg( VipsObjectClass *object_class,
358 	GParamSpec *pspec, VipsArgumentClass *argument_class,
359 	VipsBuf *buf, VipsOperationClassUsage *usage )
360 {
361 	if( usage->type ==
362 		vips_operation_class_usage_classify( argument_class ) ) {
363 		if( usage->message &&
364 			usage->n == 0 )
365 			vips_buf_appendf( buf, "%s\n", usage->message );
366 
367 		if( usage->oftype ) {
368 			vips_buf_appendf( buf, "   %-12s - %s, %s %s\n",
369 				g_param_spec_get_name( pspec ),
370 				g_param_spec_get_blurb( pspec ),
371 				(argument_class->flags & VIPS_ARGUMENT_INPUT) ?
372 					_( "input" ) : _( "output" ),
373 				g_type_name(
374 					G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
375 			vips_operation_pspec_usage( buf, pspec );
376 		}
377 		else {
378 				if( usage->n > 0 )
379 					vips_buf_appends( buf, " " );
380 				vips_buf_appends( buf,
381 					g_param_spec_get_name( pspec ) );
382 		}
383 
384 		usage->n += 1;
385 	}
386 
387 	return( NULL );
388 }
389 
390 static void
vips_operation_usage(VipsOperationClass * class,VipsBuf * buf)391 vips_operation_usage( VipsOperationClass *class, VipsBuf *buf )
392 {
393 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
394 
395 	VipsOperationClassUsage usage;
396 
397 	vips_buf_appendf( buf, "%s\n", object_class->description );
398 	vips_buf_appendf( buf, "usage:\n" );
399 
400 	/* First pass through args: show the required names.
401 	 */
402 	vips_buf_appendf( buf, "   %s ", object_class->nickname );
403 	usage.message = NULL;
404 	usage.type = USAGE_INPUTS;
405 	usage.oftype = FALSE;
406 	usage.n = 0;
407 	vips_argument_class_map( object_class,
408 		(VipsArgumentClassMapFn) vips_operation_class_usage_arg,
409 			buf, &usage );
410 	vips_buf_appends( buf, " [--option-name option-value ...]\n" );
411 
412 	/* Show required types.
413 	 */
414 	usage.message = "where:";
415 	usage.type = USAGE_INPUTS;
416 	usage.oftype = TRUE;
417 	usage.n = 0;
418 	vips_argument_class_map( object_class,
419 		(VipsArgumentClassMapFn) vips_operation_class_usage_arg,
420 			buf, &usage );
421 
422 	/* Show outputs with no input arg (eg. output maximum value for
423 	 * vips_max()).
424 	 */
425 	usage.message = "outputs:";
426 	usage.type = USAGE_NOARG_OUTPUT;
427 	usage.oftype = TRUE;
428 	usage.n = 0;
429 	vips_argument_class_map( object_class,
430 		(VipsArgumentClassMapFn) vips_operation_class_usage_arg,
431 			buf, &usage );
432 
433 	/* Show optional args.
434 	 */
435 	usage.message = "optional arguments:";
436 	usage.type = USAGE_OPTIONS;
437 	usage.oftype = TRUE;
438 	usage.n = 0;
439 	vips_argument_class_map( object_class,
440 		(VipsArgumentClassMapFn) vips_operation_class_usage_arg,
441 			buf, &usage );
442 
443 	/* Show flags.
444 	 */
445 	if( class->flags ) {
446 		GFlagsValue *value;
447 		VipsOperationFlags flags;
448 		GFlagsClass *flags_class =
449 			g_type_class_ref( VIPS_TYPE_OPERATION_FLAGS );
450 
451 		vips_buf_appendf( buf, "operation flags: " );
452 		flags = class->flags;
453 		while( flags && (value =
454 			g_flags_get_first_value( flags_class, flags )) ) {
455 			vips_buf_appendf( buf, "%s ", value->value_nick );
456 			flags &= ~value->value;
457 		}
458 		vips_buf_appends( buf, "\n" );
459 	}
460 }
461 
462 static void *
vips_operation_call_argument(VipsObject * object,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsArgumentInstance * argument_instance,void * a,void * b)463 vips_operation_call_argument( VipsObject *object, GParamSpec *pspec,
464 	VipsArgumentClass *argument_class,
465 	VipsArgumentInstance *argument_instance,
466 	void *a, void *b )
467 {
468 	VipsArgument *argument = (VipsArgument *) argument_class;
469 
470 	printf( "   %s: offset = %d ",
471 		g_param_spec_get_name( argument->pspec ),
472 		argument_class->offset );
473 	if( argument_class->flags & VIPS_ARGUMENT_REQUIRED )
474 		printf ("required " );
475 	if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT )
476 		printf ("construct " );
477 	if( argument_class->flags & VIPS_ARGUMENT_SET_ONCE )
478 		printf ("set-once " );
479 	if( argument_instance->assigned )
480 		printf ("assigned " );
481 	printf( "\n" );
482 
483 	return( NULL );
484 }
485 
486 static void
vips_operation_dump(VipsObject * object,VipsBuf * buf)487 vips_operation_dump( VipsObject *object, VipsBuf *buf )
488 {
489 	VipsOperation *operation = VIPS_OPERATION( object );
490 	VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object );
491 
492 	if( operation->found_hash )
493 		printf( "hash = %x\n", operation->hash );
494 	printf( "%s args:\n", object_class->nickname );
495 	vips_argument_map( VIPS_OBJECT( operation ),
496 		vips_operation_call_argument, NULL, NULL );
497 
498 	VIPS_OBJECT_CLASS( vips_operation_parent_class )->dump( object, buf );
499 }
500 
501 static void *
vips_operation_vips_operation_print_summary_arg(VipsObject * object,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsArgumentInstance * argument_instance,void * a,void * b)502 vips_operation_vips_operation_print_summary_arg( VipsObject *object,
503 	GParamSpec *pspec,
504 	VipsArgumentClass *argument_class,
505 	VipsArgumentInstance *argument_instance,
506 	void *a, void *b )
507 {
508 	VipsBuf *buf = (VipsBuf *) a;
509 
510 	/* Just assigned input and output construct args. _summary() is used
511 	 * for things like cache tracing, so it's useful to show output args.
512 	 */
513 	if( ((argument_class->flags & VIPS_ARGUMENT_INPUT) ||
514 		 (argument_class->flags & VIPS_ARGUMENT_OUTPUT)) &&
515 		(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
516 		argument_instance->assigned ) {
517 		const char *name = g_param_spec_get_name( pspec );
518 		GType type = G_PARAM_SPEC_VALUE_TYPE( pspec );
519 
520 		GValue gvalue = { 0, };
521 		char *str;
522 
523 		g_value_init( &gvalue, type );
524 		g_object_get_property( G_OBJECT( object ), name, &gvalue );
525 		str = g_strdup_value_contents( &gvalue );
526 		vips_buf_appendf( buf, " %s=%s", name, str );
527 		g_free( str );
528 		g_value_unset( &gvalue );
529 	}
530 
531 	return( NULL );
532 }
533 
534 static void
vips_operation_summary(VipsObject * object,VipsBuf * buf)535 vips_operation_summary( VipsObject *object, VipsBuf *buf )
536 {
537 	VipsOperation *operation = VIPS_OPERATION( object );
538 	VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object );
539 
540 	vips_buf_appendf( buf, "%s", object_class->nickname );
541 	vips_argument_map( VIPS_OBJECT( operation ),
542 		vips_operation_vips_operation_print_summary_arg, buf, NULL );
543 
544 	vips_buf_appends( buf, " -" );
545 
546 	VIPS_OBJECT_CLASS( vips_operation_parent_class )->
547 		summary( object, buf );
548 }
549 
550 static VipsOperationFlags
vips_operation_real_get_flags(VipsOperation * operation)551 vips_operation_real_get_flags( VipsOperation *operation )
552 {
553 	VipsOperationClass *class = VIPS_OPERATION_GET_CLASS( operation );
554 
555 	return( class->flags );
556 }
557 
558 static void
vips_operation_class_init(VipsOperationClass * class)559 vips_operation_class_init( VipsOperationClass *class )
560 {
561 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
562 	VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
563 
564 	gobject_class->finalize = vips_operation_finalize;
565 	gobject_class->dispose = vips_operation_dispose;
566 
567 	vobject_class->nickname = "operation";
568 	vobject_class->description = _( "operations" );
569 	vobject_class->summary = vips_operation_summary;
570 	vobject_class->dump = vips_operation_dump;
571 
572 	class->usage = vips_operation_usage;
573 	class->get_flags = vips_operation_real_get_flags;
574 
575 	vips_operation_signals[SIG_INVALIDATE] = g_signal_new( "invalidate",
576 		G_TYPE_FROM_CLASS( class ),
577 		G_SIGNAL_RUN_LAST,
578 		G_STRUCT_OFFSET( VipsOperationClass, invalidate ),
579 		NULL, NULL,
580 		g_cclosure_marshal_VOID__VOID,
581 		G_TYPE_NONE, 0 );
582 }
583 
584 static void
vips_operation_init(VipsOperation * operation)585 vips_operation_init( VipsOperation *operation )
586 {
587 }
588 
589 /**
590  * vips_operation_get_flags:
591  * @operation: operation to fetch flags from
592  *
593  * Returns the set of flags for this operation.
594  *
595  * Returns: 0 on success, or -1 on error.
596  */
597 VipsOperationFlags
vips_operation_get_flags(VipsOperation * operation)598 vips_operation_get_flags( VipsOperation *operation )
599 {
600 	VipsOperationClass *class = VIPS_OPERATION_GET_CLASS( operation );
601 
602 	return( class->get_flags( operation ) );
603 }
604 
605 /**
606  * vips_operation_class_print_usage: (skip)
607  * @operation_class: class to print usage for
608  *
609  * Print a usage message for the operation to stdout.
610  */
611 void
vips_operation_class_print_usage(VipsOperationClass * operation_class)612 vips_operation_class_print_usage( VipsOperationClass *operation_class )
613 {
614 	char str[4096];
615 	VipsBuf buf = VIPS_BUF_STATIC( str );
616 
617 	operation_class->usage( operation_class, &buf );
618 	printf( "%s", vips_buf_all( &buf ) );
619 }
620 
621 void
vips_operation_invalidate(VipsOperation * operation)622 vips_operation_invalidate( VipsOperation *operation )
623 {
624 #ifdef VIPS_DEBUG
625 	printf( "vips_operation_invalidate: %p\n", operation );
626 	vips_object_print_summary( VIPS_OBJECT( operation ) );
627 #endif /*VIPS_DEBUG*/
628 
629 	g_signal_emit( operation, vips_operation_signals[SIG_INVALIDATE], 0 );
630 }
631 
632 /**
633  * vips_operation_new: (constructor)
634  * @name: nickname of operation to create
635  *
636  * Return a new #VipsOperation with the specified nickname. Useful for
637  * language bindings.
638  *
639  * You'll need to set
640  * any arguments and build the operation before you can use it. See
641  * vips_call() for a higher-level way to make new operations.
642  *
643  * Returns: (transfer full): the new operation.
644  */
645 VipsOperation *
vips_operation_new(const char * name)646 vips_operation_new( const char *name )
647 {
648 	GType type;
649 	VipsObject *object;
650 	VipsOperation *operation;
651 
652 	vips_check_init();
653 
654 	if( !(type = vips_type_find( "VipsOperation", name )) ) {
655 		vips_error( "VipsOperation",
656 			_( "class \"%s\" not found" ), name );
657 		return( NULL );
658 	}
659 
660 	if( !(object = g_object_new( type, NULL )) ) {
661 		vips_error( "VipsOperation",
662 			_( "\"%s\" is not an instantiable class" ), name );
663 		return( NULL );
664 	}
665 
666 	operation = VIPS_OPERATION( object );
667 
668 	VIPS_DEBUG_MSG( "vips_operation_new: %s (%p)\n", name, operation );
669 
670 	return( operation );
671 }
672 
673 /* Some systems do not have va_copy() ... this might work (it does on MSVC,
674  * apparently).
675  *
676  * FIXME ... this should be in configure.in
677  */
678 #ifndef va_copy
679 #define va_copy(d,s) ((d) = (s))
680 #endif
681 
682 static int
vips_operation_set_valist_required(VipsOperation * operation,va_list ap)683 vips_operation_set_valist_required( VipsOperation *operation, va_list ap )
684 {
685 	VIPS_DEBUG_MSG( "vips_operation_set_valist_required:\n" );
686 
687 	/* Set required input arguments. Can't use vips_argument_map here
688 	 * :-( because passing va_list by reference is not portable.
689 	 */
690 	VIPS_ARGUMENT_FOR_ALL( operation,
691 		pspec, argument_class, argument_instance ) {
692 
693 		g_assert( argument_instance );
694 
695 		/* We skip deprecated required args. There will be a new,
696 		 * renamed arg in the same place.
697 		 */
698 		if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
699 			!(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) {
700 			VIPS_ARGUMENT_COLLECT_SET( pspec, argument_class, ap );
701 
702 #ifdef VIPS_DEBUG
703 			{
704 				char *str;
705 
706 				str = g_strdup_value_contents( &value );
707 				VIPS_DEBUG_MSG( "\t%s = %s\n",
708 					g_param_spec_get_name( pspec ), str );
709 				g_free( str );
710 			}
711 #endif /*VIPS_DEBUG */
712 
713 			g_object_set_property( G_OBJECT( operation ),
714 				g_param_spec_get_name( pspec ), &value );
715 
716 			VIPS_ARGUMENT_COLLECT_GET( pspec, argument_class, ap );
717 
718 #ifdef VIPS_DEBUG
719 			printf( "\tskipping arg %p for %s\n",
720 				arg, g_param_spec_get_name( pspec ) );
721 #endif /*VIPS_DEBUG */
722 
723 			VIPS_ARGUMENT_COLLECT_END
724 		}
725 	} VIPS_ARGUMENT_FOR_ALL_END
726 
727 	return( 0 );
728 }
729 
730 static int
vips_operation_get_valist_required(VipsOperation * operation,va_list ap)731 vips_operation_get_valist_required( VipsOperation *operation, va_list ap )
732 {
733 	VIPS_DEBUG_MSG( "vips_operation_get_valist_required:\n" );
734 
735 	/* Extract output arguments. Can't use vips_argument_map here
736 	 * :-( because passing va_list by reference is not portable.
737 	 */
738 	VIPS_ARGUMENT_FOR_ALL( operation,
739 		pspec, argument_class, argument_instance ) {
740 		if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) ) {
741 			VIPS_ARGUMENT_COLLECT_SET( pspec, argument_class, ap );
742 
743 			VIPS_ARGUMENT_COLLECT_GET( pspec, argument_class, ap );
744 
745 			if( !argument_instance->assigned )
746 				continue;
747 
748 #ifdef VIPS_DEBUG
749 			printf( "\twriting %s to %p\n",
750 				g_param_spec_get_name( pspec ), arg );
751 #endif /*VIPS_DEBUG */
752 
753 			/* It'd be nice to be able to test for arg being a
754 			 * valid gobject pointer, since passing in a valid
755 			 * pointer (and having us destroy it) is a common
756 			 * error and a cause of hard-to-find leaks.
757 			 *
758 			 * Unfortunately, G_IS_OBJECT() can't be given an
759 			 * arbitrary pointer for testing -- you're very likely
760 			 * to get coredumps.
761 			 */
762 
763 			g_object_get( G_OBJECT( operation ),
764 				g_param_spec_get_name( pspec ), arg, NULL );
765 
766 			/* If the pspec is an object, that will up the ref
767 			 * count. We want to hand over the ref, so we have to
768 			 * knock it down again.
769 			 */
770 			if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
771 				GObject *object;
772 
773 				object = *((GObject **) arg);
774 				g_object_unref( object );
775 			}
776 
777 			VIPS_ARGUMENT_COLLECT_END
778 		}
779 	} VIPS_ARGUMENT_FOR_ALL_END
780 
781 	return( 0 );
782 }
783 
784 static int
vips_operation_get_valist_optional(VipsOperation * operation,va_list ap)785 vips_operation_get_valist_optional( VipsOperation *operation, va_list ap )
786 {
787 	char *name;
788 
789 	VIPS_DEBUG_MSG( "vips_operation_get_valist_optional:\n" );
790 
791 	for( name = va_arg( ap, char * ); name; name = va_arg( ap, char * ) ) {
792 		GParamSpec *pspec;
793 		VipsArgumentClass *argument_class;
794 		VipsArgumentInstance *argument_instance;
795 
796 		VIPS_DEBUG_MSG( "\tname = '%s' (%p)\n", name, name );
797 
798 		if( vips_object_get_argument( VIPS_OBJECT( operation ), name,
799 			&pspec, &argument_class, &argument_instance ) )
800 			return( -1 );
801 
802 		VIPS_ARGUMENT_COLLECT_SET( pspec, argument_class, ap );
803 
804 		/* We must collect input args as we walk the name/value list,
805 		 * but we don't do anything with them.
806 		 */
807 
808 		VIPS_ARGUMENT_COLLECT_GET( pspec, argument_class, ap );
809 
810 		/* Here's an output arg.
811 		 */
812 
813 #ifdef VIPS_DEBUG
814 		printf( "\twriting %s to %p\n",
815 			g_param_spec_get_name( pspec ), arg );
816 #endif /*VIPS_DEBUG */
817 
818 		/* If the dest pointer is NULL, skip the read.
819 		 */
820 		if( arg ) {
821 			g_object_get( G_OBJECT( operation ),
822 				g_param_spec_get_name( pspec ), arg,
823 				NULL );
824 
825 			/* If the pspec is an object, that will up
826 			 * the ref count. We want to hand over the
827 			 * ref, so we have to knock it down again.
828 			 */
829 			if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
830 				GObject *object;
831 
832 				object = *((GObject **) arg);
833 				g_object_unref( object );
834 			}
835 		}
836 
837 		VIPS_ARGUMENT_COLLECT_END
838 	}
839 
840 	return( 0 );
841 }
842 
843 /**
844  * vips_call_required_optional:
845  * @operation: the operation to execute
846  * @required: %va_list of required arguments
847  * @optional: NULL-terminated %va_list of name / value pairs
848  *
849  * This is the main entry point for the C and C++ varargs APIs. @operation
850  * is executed, supplying @required and @optional arguments.
851  *
852  * Beware, this can change @operation to point at an old, cached one.
853  *
854  * Returns: 0 on success, -1 on error
855  */
856 int
vips_call_required_optional(VipsOperation ** operation,va_list required,va_list optional)857 vips_call_required_optional( VipsOperation **operation,
858 	va_list required, va_list optional )
859 {
860 	int result;
861 	va_list a;
862 	va_list b;
863 
864 	/* We need to be able to walk required and optional twice. On x64 gcc,
865 	 * vips_operation_set_valist_required() etc. will destructively alter
866 	 * the passed-in va_list. We make a copy and walk that instead.
867 	 */
868 	va_copy( a, required );
869 	va_copy( b, optional );
870 	result = vips_operation_set_valist_required( *operation, a ) ||
871 		vips_object_set_valist( VIPS_OBJECT( *operation ), b );
872 	va_end( a );
873 	va_end( b );
874 
875 	if( result )
876 		return( -1 );
877 
878 	/* Build from cache.
879 	 */
880 	if( vips_cache_operation_buildp( operation ) )
881 		return( -1 );
882 
883 	/* Walk args again, writing output.
884 	 */
885 	va_copy( a, required );
886 	va_copy( b, optional );
887 	result = vips_operation_get_valist_required( *operation, required ) ||
888 		vips_operation_get_valist_optional( *operation, optional );
889 	va_end( a );
890 	va_end( b );
891 
892 	return( result );
893 }
894 
895 static int
vips_call_by_name(const char * operation_name,const char * option_string,va_list required,va_list optional)896 vips_call_by_name( const char *operation_name,
897 	const char *option_string, va_list required, va_list optional )
898 {
899 	VipsOperation *operation;
900 	int result;
901 
902 	VIPS_DEBUG_MSG( "vips_call_by_name: starting for %s ...\n",
903 		operation_name );
904 
905 	if( !(operation = vips_operation_new( operation_name )) )
906 		return( -1 );
907 
908 	/* Set str options before vargs options, so the user can't override
909 	 * things we set deliberately.
910 	 */
911 	if( option_string &&
912 		vips_object_set_from_string( VIPS_OBJECT( operation ),
913 			option_string ) ) {
914 		vips_object_unref_outputs( VIPS_OBJECT( operation ) );
915 		g_object_unref( operation );
916 
917 		return( -1 );
918 	}
919 
920 	result = vips_call_required_optional( &operation, required, optional );
921 
922 	/* Build failed: junk args and back out.
923 	 */
924 	if( result ) {
925 		vips_object_unref_outputs( VIPS_OBJECT( operation ) );
926 		g_object_unref( operation );
927 
928 		return( -1 );
929 	}
930 
931 	/* The operation we have built should now have been reffed by one of
932 	 * its arguments or have finished its work. Either way, we can unref.
933 	 */
934 	g_object_unref( operation );
935 
936 	return( result );
937 }
938 
939 /**
940  * vips_call:
941  * @operation_name: name of operation to call
942  * @...: required args, then a %NULL-terminated list of argument/value pairs
943  *
944  * vips_call() calls the named operation, passing in required arguments and
945  * then setting any optional ones from the remainder of the arguments as a set
946  * of name/value pairs.
947  *
948  * For example, vips_embed() takes six required arguments, @in, @out, @x, @y,
949  * @width, @height, and has two optional arguments, @extend and @background.
950  * You can run it with vips_call() like this:
951  *
952  * |[
953  * VipsImage *in = ...
954  * VipsImage *out;
955  *
956  * if( vips_call( "embed", in, &out, 10, 10, 100, 100,
957  * 	"extend", VIPS_EXTEND_COPY,
958  * 	NULL ) )
959  * 	... error
960  * ]|
961  *
962  * Normally of course you'd just use the vips_embed() wrapper function and get
963  * type-safety for the required arguments.
964  *
965  * See also: vips_call_split(), vips_call_options().
966  *
967  * Returns: 0 on success, -1 on error
968  */
969 int
vips_call(const char * operation_name,...)970 vips_call( const char *operation_name, ... )
971 {
972 	VipsOperation *operation;
973 	int result;
974 	va_list required;
975 	va_list optional;
976 
977 	if( !(operation = vips_operation_new( operation_name )) )
978 		return( -1 );
979 
980 	/* We have to break the va_list into separate required and optional
981 	 * components.
982 	 *
983 	 * Note the start, grab the required, then copy and reuse.
984 	 */
985 	va_start( required, operation_name );
986 
987 	va_copy( optional, required );
988 
989 	VIPS_ARGUMENT_FOR_ALL( operation,
990 		pspec, argument_class, argument_instance ) {
991 
992 		g_assert( argument_instance );
993 
994 		if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) ) {
995 			VIPS_ARGUMENT_COLLECT_SET( pspec, argument_class,
996 				optional );
997 
998 			VIPS_ARGUMENT_COLLECT_GET( pspec, argument_class,
999 				optional );
1000 
1001 			VIPS_ARGUMENT_COLLECT_END
1002 		}
1003 	} VIPS_ARGUMENT_FOR_ALL_END
1004 
1005 	/* We just needed this operation for the arg loop.
1006 	 */
1007 	g_object_unref( operation );
1008 
1009 	result = vips_call_by_name( operation_name, NULL, required, optional );
1010 
1011 	va_end( required );
1012 	va_end( optional );
1013 
1014 	return( result );
1015 }
1016 
1017 int
vips_call_split(const char * operation_name,va_list optional,...)1018 vips_call_split( const char *operation_name, va_list optional, ... )
1019 {
1020 	int result;
1021 	va_list required;
1022 
1023 	va_start( required, optional );
1024 	result = vips_call_by_name( operation_name, NULL,
1025 		required, optional );
1026 	va_end( required );
1027 
1028 	return( result );
1029 }
1030 
1031 int
vips_call_split_option_string(const char * operation_name,const char * option_string,va_list optional,...)1032 vips_call_split_option_string( const char *operation_name,
1033 	const char *option_string, va_list optional, ... )
1034 {
1035 	int result;
1036 	va_list required;
1037 
1038 	va_start( required, optional );
1039 	result = vips_call_by_name( operation_name, option_string,
1040 		required, optional );
1041 	va_end( required );
1042 
1043 	return( result );
1044 }
1045 
1046 static void *
vips_call_find_pspec(VipsObject * object,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsArgumentInstance * argument_instance,void * a,void * b)1047 vips_call_find_pspec( VipsObject *object,
1048 	GParamSpec *pspec,
1049 	VipsArgumentClass *argument_class,
1050 	VipsArgumentInstance *argument_instance,
1051 	void *a, void *b )
1052 {
1053 	const char *name = (const char *) a;
1054 
1055 	/* One char names we assume are "-x" style abbreviations, longer names
1056 	 * we match the whole string.
1057 	 */
1058 	if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
1059 		(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
1060 		!argument_instance->assigned )
1061 		if( (strlen( name ) == 1 &&
1062 			g_param_spec_get_name( pspec )[0] == name[0]) ||
1063 			strcmp( g_param_spec_get_name( pspec ), name  ) == 0 )
1064 			return( argument_instance );
1065 
1066 	return( NULL );
1067 }
1068 
1069 /* Keep this stuff around for output args.
1070  */
1071 typedef struct _VipsCallOptionOutput {
1072 	VipsArgumentInstance *argument_instance;
1073 	char *value;
1074 } VipsCallOptionOutput;
1075 
1076 static int
vips_call_option_output(VipsObject * object,VipsCallOptionOutput * output)1077 vips_call_option_output( VipsObject *object,
1078 	VipsCallOptionOutput *output )
1079 {
1080 	VipsArgumentInstance *argument_instance = output->argument_instance;
1081 	GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec;
1082 
1083 	int result;
1084 
1085 	/* Don't look at the output arg if _build() hasn't run sucessfully, it
1086 	 * probably won't have been set.
1087 	 */
1088 	result = 0;
1089 	if( object->constructed )
1090 		result = vips_object_get_argument_to_string( object,
1091 			g_param_spec_get_name( pspec ), output->value );
1092 
1093 	return( result );
1094 }
1095 
1096 static void
vips_call_option_output_free(VipsObject * object,VipsCallOptionOutput * output)1097 vips_call_option_output_free( VipsObject *object, VipsCallOptionOutput *output )
1098 {
1099 	VIPS_FREE( output->value );
1100 	g_free( output );
1101 }
1102 
1103 static gboolean
vips_call_options_set(const gchar * option_name,const gchar * value,gpointer data,GError ** error)1104 vips_call_options_set( const gchar *option_name, const gchar *value,
1105 	gpointer data, GError **error )
1106 {
1107 	VipsOperation *operation = (VipsOperation *) data;
1108 	const char *name;
1109 	VipsArgumentInstance *argument_instance;
1110 	VipsArgumentClass *argument_class;
1111 	GParamSpec *pspec;
1112 
1113 	VIPS_DEBUG_MSG( "vips_call_options_set: %s = %s\n",
1114 		option_name, value );
1115 
1116 	/* Remove any leading "--" from the option name.
1117 	 */
1118 	for( name = option_name; *name == '-'; name++ )
1119 		;
1120 
1121 	if( !(argument_instance = (VipsArgumentInstance *)
1122 		vips_argument_map(
1123 			VIPS_OBJECT( operation ),
1124 			vips_call_find_pspec, (void *) name, NULL )) ) {
1125 		vips_error( VIPS_OBJECT_GET_CLASS( operation )->nickname,
1126 			_( "unknown argument '%s'" ), name );
1127 		vips_error_g( error );
1128 		return( FALSE );
1129 	}
1130 	argument_class = argument_instance->argument_class;
1131 	pspec = ((VipsArgument *) argument_instance)->pspec;
1132 
1133 	if( (argument_class->flags & VIPS_ARGUMENT_INPUT) ) {
1134 		if( vips_object_set_argument_from_string(
1135 			VIPS_OBJECT( operation ),
1136 			g_param_spec_get_name( pspec ), value ) ) {
1137 			vips_error_g( error );
1138 			return( FALSE );
1139 		}
1140 
1141 #ifdef VIPS_DEBUG
1142 {
1143 		GType type = G_PARAM_SPEC_VALUE_TYPE( pspec );
1144 		GValue gvalue = { 0, };
1145 		char *str;
1146 
1147 		g_value_init( &gvalue, type );
1148 		g_object_get_property( G_OBJECT( operation ),
1149 			g_param_spec_get_name( pspec ), &gvalue );
1150 		str = g_strdup_value_contents( &gvalue );
1151 		VIPS_DEBUG_MSG( "\tGValue %s = %s\n",
1152 			g_param_spec_get_name( pspec ), str );
1153 		g_free( str );
1154 		g_value_unset( &gvalue );
1155 }
1156 #endif /*VIPS_DEBUG*/
1157 	}
1158 	else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) {
1159 		VipsCallOptionOutput *output;
1160 
1161 		/* We can't do output now, we have to attach a callback to do
1162 		 * the processing after the operation has run.
1163 		 */
1164 		output = g_new( VipsCallOptionOutput, 1 );
1165 		output->argument_instance = argument_instance;
1166 		output->value = g_strdup( value );
1167 		g_signal_connect( operation, "postbuild",
1168 			G_CALLBACK( vips_call_option_output ),
1169 			output );
1170 		g_signal_connect( operation, "close",
1171 			G_CALLBACK( vips_call_option_output_free ),
1172 			output );
1173 	}
1174 
1175 	return( TRUE );
1176 }
1177 
1178 static void *
vips_call_options_add(VipsObject * object,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsArgumentInstance * argument_instance,void * a,void * b)1179 vips_call_options_add( VipsObject *object,
1180 	GParamSpec *pspec,
1181 	VipsArgumentClass *argument_class,
1182 	VipsArgumentInstance *argument_instance,
1183 	void *a, void *b )
1184 {
1185 	GOptionGroup *group = (GOptionGroup *) a;
1186 
1187 	if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
1188 		(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
1189 		!argument_instance->assigned ) {
1190 		const char *name = g_param_spec_get_name( pspec );
1191 		gboolean needs_string =
1192 			vips_object_argument_needsstring( object, name );
1193 		GOptionEntry entry[2];
1194 
1195 		entry[0].long_name = name;
1196 		entry[0].description = g_param_spec_get_blurb( pspec );
1197 
1198 		/* Don't set short names for deprecated args.
1199 		 */
1200 		if( argument_class->flags & VIPS_ARGUMENT_DEPRECATED )
1201 			entry[0].short_name = '\0';
1202 		else
1203 			entry[0].short_name = name[0];
1204 
1205 		entry[0].flags = 0;
1206 		if( !needs_string )
1207 			entry[0].flags |= G_OPTION_FLAG_NO_ARG;
1208 		if( argument_class->flags & VIPS_ARGUMENT_DEPRECATED )
1209 			entry[0].flags |= G_OPTION_FLAG_HIDDEN;
1210 
1211 		entry[0].arg = G_OPTION_ARG_CALLBACK;
1212 		entry[0].arg_data = (gpointer) vips_call_options_set;
1213 		if( needs_string )
1214 			entry[0].arg_description =
1215 				g_type_name( G_PARAM_SPEC_VALUE_TYPE( pspec ) );
1216 		else
1217 			entry[0].arg_description = NULL;
1218 
1219 		entry[1].long_name = NULL;
1220 
1221 		VIPS_DEBUG_MSG( "vips_call_options_add: adding %s\n", name );
1222 
1223 		g_option_group_add_entries( group, &entry[0] );
1224 	}
1225 
1226 	return( NULL );
1227 }
1228 
1229 void
vips_call_options(GOptionGroup * group,VipsOperation * operation)1230 vips_call_options( GOptionGroup *group, VipsOperation *operation )
1231 {
1232 	(void) vips_argument_map( VIPS_OBJECT( operation ),
1233 		vips_call_options_add, group, NULL );
1234 }
1235 
1236 /* What we track during an argv call.
1237  */
1238 typedef struct _VipsCall {
1239 	VipsOperation *operation;
1240 	int argc;
1241 	char **argv;
1242 	int i;
1243 } VipsCall;
1244 
1245 static const char *
vips_call_get_arg(VipsCall * call,int i)1246 vips_call_get_arg( VipsCall *call, int i )
1247 {
1248 	if( i < 0 ||
1249 		i >= call->argc ) {
1250 		vips_error( VIPS_OBJECT_GET_CLASS( call->operation )->nickname,
1251 			"%s", _( "too few arguments" ) );
1252 		return( NULL );
1253 	}
1254 
1255 	return( call->argv[i] );
1256 }
1257 
1258 static void *
vips_call_argv_input(VipsObject * object,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsArgumentInstance * argument_instance,void * a,void * b)1259 vips_call_argv_input( VipsObject *object,
1260 	GParamSpec *pspec,
1261 	VipsArgumentClass *argument_class,
1262 	VipsArgumentInstance *argument_instance,
1263 	void *a, void *b )
1264 {
1265 	VipsCall *call = (VipsCall *) a;
1266 
1267 	/* Loop over all required construct args.
1268 	 */
1269 	if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
1270 		(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
1271 		!(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) {
1272 		const char *name = g_param_spec_get_name( pspec );
1273 
1274 		if( (argument_class->flags & VIPS_ARGUMENT_INPUT) ) {
1275 			const char *arg;
1276 
1277 			if( !(arg = vips_call_get_arg( call, call->i )) ||
1278 				vips_object_set_argument_from_string( object,
1279 					name, arg ) )
1280 				return( pspec );
1281 
1282 			call->i += 1;
1283 		}
1284 		else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) {
1285 			if( vips_object_argument_needsstring( object, name ) )
1286 				call->i += 1;
1287 		}
1288 	}
1289 
1290 	return( NULL );
1291 }
1292 
1293 static void *
vips_call_argv_output(VipsObject * object,GParamSpec * pspec,VipsArgumentClass * argument_class,VipsArgumentInstance * argument_instance,void * a,void * b)1294 vips_call_argv_output( VipsObject *object,
1295 	GParamSpec *pspec,
1296 	VipsArgumentClass *argument_class,
1297 	VipsArgumentInstance *argument_instance,
1298 	void *a, void *b )
1299 {
1300 	VipsCall *call = (VipsCall *) a;
1301 
1302 	/* Loop over all required construct args.
1303 	 */
1304 	if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
1305 		(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
1306 		!(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) {
1307 		if( (argument_class->flags & VIPS_ARGUMENT_INPUT) )
1308 			call->i += 1;
1309 		else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) {
1310 			const char *name = g_param_spec_get_name( pspec );
1311 			const char *arg;
1312 
1313 			arg = NULL;
1314 			if( vips_object_argument_needsstring( object, name ) ) {
1315 				arg = vips_call_get_arg( call, call->i );
1316 				if( !arg )
1317 					return( pspec );
1318 
1319 				call->i += 1;
1320 			}
1321 
1322 			if( vips_object_get_argument_to_string( object,
1323 				name, arg ) )
1324 				return( pspec );
1325 		}
1326 	}
1327 
1328 	return( NULL );
1329 }
1330 
1331 /* Our main command-line entry point. Optional args should have been set by
1332  * the GOption parser already, see above.
1333  *
1334  * We don't create the operation, so we must not unref it. The caller must
1335  * unref on error too. The caller must also call vips_object_unref_outputs() on
1336  * all code paths.
1337  */
1338 int
vips_call_argv(VipsOperation * operation,int argc,char ** argv)1339 vips_call_argv( VipsOperation *operation, int argc, char **argv )
1340 {
1341 	VipsCall call;
1342 
1343 	g_assert( argc >= 0 );
1344 
1345 #ifdef VIPS_DEBUG
1346 	printf( "vips_call_argv: " );
1347 	vips_object_print_name( VIPS_OBJECT( operation ) );
1348 	printf( "\n" );
1349 {
1350 	int i;
1351 
1352 	for( i = 0; i < argc; i++ )
1353 		printf( "%d) %s\n", i, argv[i] );
1354 }
1355 #endif /*VIPS_DEBUG*/
1356 
1357 	call.operation = operation;
1358 	call.argc = argc;
1359 	call.argv = argv;
1360 
1361 	call.i = 0;
1362 	if( vips_argument_map( VIPS_OBJECT( operation ),
1363 		vips_call_argv_input, &call, NULL ) )
1364 		return( -1 );
1365 
1366 	/* Any unused arguments? We must fail. Consider eg. "vips bandjoin a b
1367 	 * c". This would overwrite b with a and ignore c, potentially
1368 	 * disastrous.
1369 	 */
1370 	if( argc > call.i ) {
1371 		vips_error( VIPS_OBJECT_GET_CLASS( operation )->nickname,
1372 			"%s", _( "too many arguments" ) );
1373 		return( -1 );
1374 	}
1375 
1376 	/* We can't use the operation cache, we need to be able to change the
1377 	 * operation pointer. The cache probably wouldn't help anyway.
1378 	 */
1379 	if( vips_object_build( VIPS_OBJECT( operation ) ) )
1380 		return( -1 );
1381 
1382 	/* We're not using the cache, so we need to print the trace line.
1383 	 */
1384 	if( vips__cache_trace ) {
1385 		printf( "vips cache : " );
1386 		vips_object_print_summary( VIPS_OBJECT( operation ) );
1387 	}
1388 
1389 	call.i = 0;
1390 	if( vips_argument_map( VIPS_OBJECT( operation ),
1391 		vips_call_argv_output, &call, NULL ) )
1392 		return( -1 );
1393 
1394 	return( 0 );
1395 }
1396