1 /* Call vips functions from the graph reducer.
2  */
3 
4 /*
5 
6     Copyright (C) 1991-2003 The National Gallery
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 
22  */
23 
24 /*
25 
26     These files are distributed with CALL - http://www.vips.ecs.soton.ac.uk
27 
28  */
29 
30 #include "ip.h"
31 
32 /*
33 #define DEBUG_TIME
34 #define DEBUG
35  */
36 
37 /* This is usually turned on from a -D in cflags.
38 #define DEBUG_LEAK
39  */
40 
41 /* Often want it off ... we get spurious complaints about leaks if an
42  * operation has no images in or out (eg. im_version) because it'll never
43  * get GCed.
44 #undef DEBUG_LEAK
45  */
46 
47 /* CALL argument types we support. Keep order in sync with CallArgumentType.
48  */
49 static im_arg_type call_supported[] = {
50 	IM_TYPE_DOUBLE,
51 	IM_TYPE_INT,
52 	IM_TYPE_COMPLEX,
53 	IM_TYPE_STRING,
54 	IM_TYPE_IMAGE,
55 	IM_TYPE_DOUBLEVEC,
56 	IM_TYPE_DMASK,
57 	IM_TYPE_IMASK,
58 	IM_TYPE_IMAGEVEC,
59 	IM_TYPE_INTVEC,
60 	IM_TYPE_GVALUE,
61 	IM_TYPE_INTERPOLATE
62 };
63 
64 static iObjectClass *parent_class = NULL;
65 
66 /* All the CallInfo we make ... for leak and sanity testing. Build this file
67  * with DEBUG_LEAK to enable add/remove to this list.
68  */
69 GSList *call_info_all = NULL;
70 
71 void
call_check_all_destroyed(void)72 call_check_all_destroyed( void )
73 {
74 #ifdef DEBUG_LEAK
75 	int n_leaks;
76 	GSList *p;
77 
78 	n_leaks = 0;
79 	for( p = call_info_all; p; p = p->next ) {
80 		CallInfo *vi = (CallInfo *) p->data;
81 
82 		/* Operations which don't take an image as either an input or
83 		 * output will stay in the cache. Don't report them.
84 		 */
85 		if( vi->ninii || vi->noutii ) {
86 			n_leaks += 1;
87 			printf( "\t%s\n", vi->name );
88 		}
89 	}
90 
91 	if( n_leaks )
92 		printf( "** %d CallInfo leaked!\n", n_leaks );
93 #endif /*DEBUG_LEAK*/
94 }
95 
96 /* Does a vips argument type require an argument from nip2?
97  */
98 gboolean
call_type_needs_input(im_type_desc * ty)99 call_type_needs_input( im_type_desc *ty )
100 {
101 	/* We supply these.
102 	 */
103 	if( strcmp( ty->type, IM_TYPE_DISPLAY ) == 0 )
104 		return( FALSE );
105 
106 	if( !(ty->flags & IM_TYPE_OUTPUT) )
107 		return( TRUE );
108 
109 	if( ty->flags & IM_TYPE_RW )
110 		return( TRUE );
111 
112 	return( FALSE );
113 }
114 
115 /* Will a vips argument type generate a result for nip2?
116  */
117 gboolean
call_type_makes_output(im_type_desc * ty)118 call_type_makes_output( im_type_desc *ty )
119 {
120 	/* We ignore these.
121 	 */
122 	if( strcmp( ty->type, IM_TYPE_DISPLAY ) == 0 )
123 		return( FALSE );
124 
125 	if( ty->flags & (IM_TYPE_OUTPUT | IM_TYPE_RW) )
126 		return( TRUE );
127 
128 	return( FALSE );
129 }
130 
131 /* Error early on .. we can't print args yet.
132  */
133 void
call_error(CallInfo * vi)134 call_error( CallInfo *vi )
135 {
136 	error_top( _( "CALL library error." ) );
137 	error_sub( _( "Error calling library function \"%s\" (%s)." ),
138 		vi->name, vi->fn->desc );
139 }
140 
141 /* Get the args from the heap.
142  */
143 static void
call_args_heap(CallInfo * vi,HeapNode ** arg,VipsBuf * buf)144 call_args_heap( CallInfo *vi, HeapNode **arg, VipsBuf *buf )
145 {
146 	int i;
147 
148 	vips_buf_appendf( buf, _( "You passed:" ) );
149 	vips_buf_appendf( buf, "\n" );
150 	for( i = 0; i < vi->nargs; i++ ) {
151 		im_arg_desc *varg = &vi->fn->argv[vi->inpos[i]];
152 		PElement rhs;
153 
154 		PEPOINTRIGHT( arg[vi->nargs - i - 1], &rhs );
155 		vips_buf_appendf( buf, "  %s - ", varg->name );
156 		itext_value_ev( vi->rc, buf, &rhs );
157 		vips_buf_appendf( buf, "\n" );
158 	}
159 }
160 
161 /* Make a usage error for a CALL function.
162  */
163 void
call_usage(VipsBuf * buf,im_function * fn)164 call_usage( VipsBuf *buf, im_function *fn )
165 {
166 	im_package *pack = im_package_of_function( fn->name );
167 	char input[MAX_STRSIZE];
168 	char output[MAX_STRSIZE];
169 	int nout, nin;
170 	int i;
171 
172 	strcpy( input, "" );
173 	strcpy( output, "" );
174 	nin = 0;
175 	nout = 0;
176 	for( i = 0; i < fn->argc; i++ ) {
177 		im_arg_desc *arg = &fn->argv[i];
178 		char line[256];
179 
180 		/* Format name, type message.
181 		 */
182 		im_snprintf( line, 256,
183 			"   %s  - %s\n", arg->name, arg->desc->type );
184 
185 		if( call_type_makes_output( arg->desc ) ) {
186 			strcat( output, line );
187 			nout++;
188 		}
189 
190 		if( call_type_needs_input( arg->desc ) ) {
191 			strcat( input, line );
192 			nin++;
193 		}
194 	}
195 
196 	vips_buf_appendf( buf, _( "Usage:" ) );
197         vips_buf_appends( buf, "\n" );
198         vips_buf_appendf( buf, _( "CALL operator \"%s\"" ), fn->name );
199         vips_buf_appends( buf, "\n" );
200         vips_buf_appendf( buf, _( "%s, from package \"%s\"" ),
201 		fn->desc, pack->name );
202         vips_buf_appends( buf, "\n" );
203 
204 	vips_buf_appendf( buf,
205 		ngettext( "\"%s\" takes %d argument:",
206 			"\"%s\" takes %d arguments:",
207 			nin ),
208 		fn->name, nin );
209         vips_buf_appendf( buf, "\n%s", input );
210 
211 	vips_buf_appendf( buf,
212 		ngettext( "And produces %d result:",
213 			"And produces %d results:",
214 			nout ),
215 		nout );
216 	vips_buf_appendf( buf, "\n%s", output );
217 
218         /* Print any flags this function has.
219          */
220         vips_buf_appendf( buf, _( "Flags:" ) );
221         vips_buf_appends( buf, "\n" );
222 	vips_buf_appendf( buf, "   (" );
223         if( fn->flags & IM_FN_PIO )
224                 vips_buf_appendf( buf, _( "PIO function" ) );
225         else
226                 vips_buf_appendf( buf, _( "WIO function" ) );
227 	vips_buf_appendf( buf, ") (" );
228         if( fn->flags & IM_FN_TRANSFORM )
229                 vips_buf_appendf( buf, _( "coordinate transformer" ) );
230         else
231                 vips_buf_appendf( buf, _( "no coordinate transformation" ) );
232 	vips_buf_appendf( buf, ") (" );
233         if( fn->flags & IM_FN_PTOP )
234                 vips_buf_appendf( buf, _( "point-to-point operation" ) );
235         else
236                 vips_buf_appendf( buf, _( "area operation" ) );
237 	vips_buf_appendf( buf, ") (" );
238         if( fn->flags & IM_FN_NOCACHE )
239                 vips_buf_appendf( buf, _( "uncacheable operation" ) );
240         else
241                 vips_buf_appendf( buf, _( "operation can be cached" ) );
242         vips_buf_appendf( buf, ")\n" );
243 }
244 
245 /* We know there's a problem exporting a particular arg to CALL.
246  */
247 static void
call_error_arg(CallInfo * vi,HeapNode ** arg,int argi)248 call_error_arg( CallInfo *vi, HeapNode **arg, int argi )
249 {
250 	char txt[10000];
251 	VipsBuf buf = VIPS_BUF_STATIC( txt );
252 
253 	error_top( _( "Bad argument." ) );
254 
255 	vips_buf_appendf( &buf,
256 		_( "Argument %d (%s) to \"%s\" is the wrong type." ),
257 		argi + 1, vi->fn->argv[vi->inpos[argi]].name, vi->name );
258 	vips_buf_appendf( &buf, "\n" );
259 	call_args_heap( vi, arg, &buf );
260 	vips_buf_appendf( &buf, "\n" );
261 	call_usage( &buf, vi->fn );
262 	error_sub( "%s", vips_buf_all( &buf ) );
263 }
264 
265 /* Too many args.
266  */
267 void
call_error_toomany(CallInfo * vi)268 call_error_toomany( CallInfo *vi )
269 {
270 	char txt[1000];
271 	VipsBuf buf = VIPS_BUF_STATIC( txt );
272 
273 	error_top( _( "Too many arguments." ) );
274 
275 	vips_buf_appendf( &buf,
276 		_( "Too many arguments to \"%s\"." ),
277 		vi->name );
278 	vips_buf_appendf( &buf, "\n" );
279 	call_usage( &buf, vi->fn );
280 	error_sub( "%s", vips_buf_all( &buf ) );
281 }
282 
283 /* Look up a CALL type.
284  */
285 CallArgumentType
call_lookup_type(im_arg_type type)286 call_lookup_type( im_arg_type type )
287 {
288 	int i;
289 
290 	for( i = 0; i < IM_NUMBER( call_supported ); i++ )
291 		if( strcmp( type, call_supported[i] ) == 0 )
292 			return( (CallArgumentType) i );
293 
294 	error_top( _( "Unknown type." ) );
295 	error_sub( _( "CALL type \"%s\" not supported" ), type );
296 
297 	return( CALL_NONE );
298 }
299 
300 /* Is this the sort of CALL function we can call?
301  */
302 gboolean
call_is_callable(im_function * fn)303 call_is_callable( im_function *fn )
304 {
305 	int i;
306 	int nout;
307 	int nin;
308 
309 	if( fn->argc >= MAX_CALL_ARGS )
310 		return( FALSE );
311 
312         /* Check all argument types are supported. As well as the arg types
313          * spotted by call_lookup_type, we also allow IM_TYPE_DISPLAY.
314          */
315         for( i = 0; i < fn->argc; i++ ) {
316                 im_arg_desc *arg = &fn->argv[i];
317                 im_arg_type vt = arg->desc->type;
318 
319                 if( call_lookup_type( vt ) == CALL_NONE ) {
320                         /* Unknown type .. if DISPLAY it's OK.
321                          */
322                         if( strcmp( vt, IM_TYPE_DISPLAY ) != 0 )
323                                 return( FALSE );
324                 }
325         }
326 
327         nin = nout = 0;
328         for( i = 0; i < fn->argc; i++ ) {
329 		im_type_desc *ty = fn->argv[i].desc;
330 
331 		if( call_type_makes_output( ty ) )
332 			nout += 1;
333 
334 		if( call_type_needs_input( ty ) )
335 			nin += 1;
336 	}
337 
338         /* Must be at least one output argument.
339          */
340 
341         /* Must be at least one output argument.
342          */
343         if( nout == 0 )
344                 return( FALSE );
345 
346 	/* Need at least 1 input argument: we reply on having an application
347 	 * node to overwrite with (I result).
348 	 */
349         if( nin == 0 )
350                 return( FALSE );
351 
352 	return( TRUE );
353 }
354 
355 /* Count the number of args a CALL function needs.
356  */
357 int
call_n_args(im_function * fn)358 call_n_args( im_function *fn )
359 {
360 	int i;
361 	int nin;
362 
363         for( nin = 0, i = 0; i < fn->argc; i++ ) {
364 		im_type_desc *ty = fn->argv[i].desc;
365 
366 		if( call_type_needs_input( ty ) )
367                         nin += 1;
368         }
369 
370 	return( nin );
371 }
372 
373 /* Make an im_doublevec_object.
374  */
375 static int
call_make_doublevec(im_doublevec_object * dv,int n,double * vec)376 call_make_doublevec( im_doublevec_object *dv, int n, double *vec )
377 {
378 	int i;
379 
380 	dv->n = n;
381 	dv->vec = NULL;
382 
383 	if( n > 0 ) {
384 		if( !(dv->vec = IARRAY( NULL, n, double )) )
385 			return( -1 );
386 		for( i = 0; i < n; i++ )
387 			dv->vec[i] = vec[i];
388 	}
389 
390 	return( 0 );
391 }
392 
393 /* Make an im_intvec_object. Make from a vec of doubles, because that's what
394  * we get from nip.
395  */
396 static int
call_make_intvec(im_intvec_object * dv,int n,double * vec)397 call_make_intvec( im_intvec_object *dv, int n, double *vec )
398 {
399 	int i;
400 
401 	dv->n = n;
402 	dv->vec = NULL;
403 
404 	if( n > 0 ) {
405 		if( !(dv->vec = IARRAY( NULL, n, int )) )
406 			return( -1 );
407 		for( i = 0; i < n; i++ )
408 			dv->vec[i] = vec[i];
409 	}
410 
411 	return( 0 );
412 }
413 
414 /* Make an im_imagevec_object.
415  */
416 static int
call_make_imagevec(im_imagevec_object * iv,int n)417 call_make_imagevec( im_imagevec_object *iv, int n )
418 {
419 	int i;
420 
421 	iv->n = n;
422 	iv->vec = NULL;
423 
424 	if( n > 0 ) {
425 		if( !(iv->vec = IARRAY( NULL, n, IMAGE * )) )
426 			return( -1 );
427 		for( i = 0; i < n; i++ )
428 			iv->vec[i] = NULL;
429 	}
430 
431 	return( 0 );
432 }
433 
434 /* Add another ii to inii.
435  */
436 static gboolean
call_add_input_ii(CallInfo * vi,Imageinfo * ii)437 call_add_input_ii( CallInfo *vi, Imageinfo *ii )
438 {
439 	if( vi->ninii > MAX_CALL_ARGS ) {
440 		call_error_toomany( vi );
441 		return( FALSE );
442 	}
443 
444 	vi->inii[vi->ninii] = ii;
445 	vi->ninii += 1;
446 
447 	/* We hold a ref to the ii until the call is done and the result
448 	 * written back to nip2. If we cache the result, we make a new
449 	 * weakref.
450 	 */
451 	managed_dup_nonheap( MANAGED( ii ) );
452 	vi->must_drop = TRUE;
453 
454 	return( TRUE );
455 }
456 
457 /* ip types -> CALL types. Write to obj. FALSE for no conversion possible.
458  */
459 static gboolean
call_fromip(CallInfo * vi,int i,PElement * arg)460 call_fromip( CallInfo *vi, int i, PElement *arg )
461 {
462 	im_type_desc *ty = vi->fn->argv[i].desc;
463 	CallArgumentType vt = call_lookup_type( ty->type );
464 	im_object *obj = &vi->vargv[i];
465 
466 	/* If call_lookup_type failed, is it the special DISPLAY type?
467 	 */
468 	if( vt == CALL_NONE && strcmp( ty->type, IM_TYPE_DISPLAY ) != 0 )
469 		/* Unknown type, and it's not DISPLAY. Flag an error.
470 		 */
471 		return( FALSE );
472 
473 	switch( vt ) {
474 	case CALL_NONE:	/* IM_TYPE_DISPLAY */
475 		/* Just use IM_TYPE_sRGB.
476 		 */
477 		*obj = im_col_displays( 7 );
478 
479 		break;
480 
481 	case CALL_DOUBLE:
482 	{
483 		double *a = *obj;
484 
485 		if( !PEISREAL( arg ) )
486 			return( FALSE );
487 		*a = PEGETREAL( arg );
488 
489 		break;
490 	}
491 
492 	case CALL_INT:
493 	{
494 		int *i = *obj;
495 
496 		if( PEISREAL( arg ) ) {
497 			double t = PEGETREAL( arg );
498 
499 			*i = (int) t;
500 		}
501 		else if( PEISBOOL( arg ) )
502 			*i = PEGETBOOL( arg );
503 		else
504 			return( FALSE );
505 
506 		break;
507 	}
508 
509 	case CALL_COMPLEX:
510 	{
511 		double *c = *obj;
512 
513 		if( !PEISCOMPLEX( arg ) )
514 			return( FALSE );
515 		c[0] = PEGETREALPART( arg );
516 		c[1] = PEGETIMAGPART( arg );
517 
518 		break;
519 	}
520 
521 	case CALL_STRING:
522 	{
523 		char **c = (char **) obj;
524 		char buf[MAX_STRSIZE];
525 
526 		if( !heap_get_string( arg, buf, MAX_STRSIZE ) )
527 			return( FALSE );
528 		*c = im_strdup( NULL, buf );
529 
530 		break;
531 	}
532 
533 	case CALL_IMAGE:
534 		/* Just note the Imageinfo for now ... a later pass sets vargv
535 		 * once we've checked all the LUTs.
536 		 */
537 		if( !PEISIMAGE( arg ) ||
538 			!call_add_input_ii( vi, IMAGEINFO( PEGETII( arg ) ) ) )
539 			return( FALSE );
540 
541 		break;
542 
543 	case CALL_DOUBLEVEC:
544 	{
545 		double buf[MAX_VEC];
546 		int n;
547 
548 		if( (n = heap_get_realvec( arg, buf, MAX_VEC )) < 0 ||
549 			call_make_doublevec( *obj, n, buf ) )
550 			return( FALSE );
551 
552 		break;
553 	}
554 
555 	case CALL_INTVEC:
556 	{
557 		double buf[MAX_VEC];
558 		int n;
559 
560 		if( (n = heap_get_realvec( arg, buf, MAX_VEC )) < 0 ||
561 			call_make_intvec( *obj, n, buf ) )
562 			return( FALSE );
563 
564 		break;
565 	}
566 
567 	case CALL_IMAGEVEC:
568 	{
569 		Imageinfo *buf[MAX_VEC];
570 		int n;
571 		int i;
572 
573 		/* Put Imageinfo in for now ... a later pass changes this to
574 		 * IMAGE* once we've checked all the LUTs.
575 		 */
576 		if( (n = heap_get_imagevec( arg, buf, MAX_VEC )) < 0 ||
577 			call_make_imagevec( *obj, n ) )
578 			return( FALSE );
579 
580 		for( i = 0; i < n; i++ )
581 			if( !call_add_input_ii( vi, buf[i] ) )
582 				return( FALSE );
583 
584 		break;
585 	}
586 
587 	case CALL_DMASK:
588 	case CALL_IMASK:
589 	{
590 		im_mask_object **mo = (im_mask_object **) obj;
591 
592 		if( vt == 6 ) {
593 			DOUBLEMASK *mask;
594 
595 			if( !(mask = matrix_ip_to_dmask( arg )) )
596 				return( FALSE );
597 			(*mo)->mask = mask;
598 			(*mo)->name = im_strdupn( mask->filename );
599 		}
600 		else {
601 			INTMASK *mask;
602 
603 			if( !(mask = matrix_ip_to_imask( arg )) )
604 				return( FALSE );
605 			(*mo)->mask = mask;
606 			(*mo)->name = im_strdupn( mask->filename );
607 		}
608 
609 		break;
610 	}
611 
612 	case CALL_GVALUE:
613 	{
614 		GValue *value = *obj;
615 
616 		memset( value, 0, sizeof( GValue ) );
617 		if( !heap_ip_to_gvalue( arg, value ) )
618 			return( FALSE );
619 
620 		break;
621 	}
622 
623 	case CALL_INTERPOLATE:
624 		if( !PEISMANAGEDGOBJECT( arg ) )
625 			return( FALSE );
626 		*obj = PEGETMANAGEDGOBJECT( arg );
627 
628 		break;
629 
630 	default:
631 		g_assert( FALSE );
632 	}
633 
634 	return( TRUE );
635 }
636 
637 /* CALL types -> ip types. Write to arg. Use outiiindex to iterate through
638  * outii[] as we find output imageinfo.
639  */
640 static gboolean
call_toip(CallInfo * vi,int i,int * outiiindex,PElement * arg)641 call_toip( CallInfo *vi, int i, int *outiiindex, PElement *arg )
642 {
643 	im_object obj = vi->vargv[i];
644 	im_type_desc *ty = vi->fn->argv[i].desc;
645 
646 #ifdef DEBUG
647 	printf( "call_toip: arg[%d] (%s) = ", i, ty->type );
648 #endif /*DEBUG*/
649 
650 	switch( call_lookup_type( ty->type ) ) {
651 	case CALL_DOUBLE:
652 		if( !heap_real_new( vi->rc->heap, *((double*)obj), arg ) )
653 			return( FALSE );
654 
655 		break;
656 
657 	case CALL_INT:
658 		if( !heap_real_new( vi->rc->heap, *((int*)obj), arg ) )
659 			return( FALSE );
660 
661 		break;
662 
663 	case CALL_DOUBLEVEC:
664 	{
665 		im_doublevec_object *dv = obj;
666 
667 		if( !heap_realvec_new( vi->rc->heap, dv->n, dv->vec, arg ) )
668 			return( FALSE );
669 
670 		break;
671 	}
672 
673 	case CALL_INTVEC:
674 	{
675 		im_intvec_object *iv = obj;
676 
677 		if( !heap_intvec_new( vi->rc->heap, iv->n, iv->vec, arg ) )
678 			return( FALSE );
679 
680 		break;
681 	}
682 
683 	case CALL_COMPLEX:
684 		if( !heap_complex_new( vi->rc->heap,
685 			((double*)obj)[0], ((double*)obj)[1], arg ) )
686 			return( FALSE );
687 
688 		break;
689 
690 	case CALL_STRING:
691 		if( !heap_managedstring_new( vi->rc->heap, (char *) obj, arg ) )
692 			return( FALSE );
693 
694 		break;
695 
696 	case CALL_IMAGE:
697 	{
698 		Imageinfo *outii;
699 
700 		outii = vi->outii[*outiiindex];
701 		*outiiindex += 1;
702 
703 		PEPUTP( arg, ELEMENT_MANAGED, outii );
704 
705 		break;
706 	}
707 
708 	case CALL_DMASK:
709 	{
710 		im_mask_object *mo = obj;
711 		DOUBLEMASK *mask = mo->mask;
712 
713 		if( !matrix_dmask_to_heap( vi->rc->heap, mask, arg ) )
714 			return( FALSE );
715 
716 		break;
717 	}
718 
719 	case CALL_IMASK:
720 	{
721 		im_mask_object *mo = obj;
722 		INTMASK *mask = mo->mask;
723 
724 		if( !matrix_imask_to_heap( vi->rc->heap, mask, arg ) )
725 			return( FALSE );
726 
727 		break;
728 	}
729 
730 	case CALL_GVALUE:
731 		if( !heap_gvalue_to_ip( (GValue *) obj, arg ) )
732 			return( FALSE );
733 
734 		break;
735 
736 	case CALL_IMAGEVEC:
737 	case CALL_INTERPOLATE:
738 	default:
739 		g_assert( FALSE );
740 	}
741 
742 #ifdef DEBUG
743 	pgraph( arg );
744 #endif /*DEBUG*/
745 
746 	return( TRUE );
747 }
748 
749 static void *
call_write_result_sub(Reduce * rc,PElement * safe,CallInfo * vi,PElement * out)750 call_write_result_sub( Reduce *rc, PElement *safe, CallInfo *vi, PElement *out )
751 {
752 	int outiiindex;
753 
754 	/* call_toip() uses this to iterate through outii[].
755 	 */
756 	outiiindex = 0;
757 
758 	/* Write result.
759 	 */
760 	if( vi->nres == 1 ) {
761 		/* Single result.
762 		 */
763 		if( !call_toip( vi, vi->outpos[0], &outiiindex, safe ) )
764 			return( out );
765 	}
766 	else {
767 		/* Have to build a list of results.
768 		 */
769 		PElement list;
770 		PElement t;
771 		int i;
772 
773 		list = *safe;
774 		heap_list_init( &list );
775 		for( i = 0; i < vi->nres; i++ ) {
776 			if( !heap_list_add( vi->rc->heap, &list, &t ) ||
777 				!call_toip( vi,
778 					vi->outpos[i], &outiiindex, &t ) )
779 				return( out );
780 
781 			(void) heap_list_next( &list );
782 		}
783 	}
784 
785 	/* Now overwrite out with safe.
786 	 */
787 	PEPUTPE( out, safe );
788 
789 	return( NULL );
790 }
791 
792 /* Write the results back to the heap. We have to so this in two stages:
793  * build the output object linked off a new managed Element, then once it's
794  * built, overwrite our output
795  */
796 static gboolean
call_write_result(CallInfo * vi,PElement * out)797 call_write_result( CallInfo *vi, PElement *out )
798 {
799 	if( reduce_safe_pointer( vi->rc,
800 		(reduce_safe_pointer_fn) call_write_result_sub,
801 		vi, out, NULL, NULL ) )
802 		return( FALSE );
803 
804 	return( TRUE );
805 }
806 
807 /* Junk all the refs we were holding during the call. See call_add_input_ii()
808  * and call_add_output_ii().
809  *
810  * This gets called explicitly after we have handed the ii refs back to nip2
811  * during normal processing, or from _dispose() if we bomb out early and
812  * unref.
813  */
814 static void
call_drop_refs(CallInfo * vi)815 call_drop_refs( CallInfo *vi )
816 {
817 	if( vi->must_drop ) {
818 		int i;
819 
820 #ifdef DEBUG
821 		printf( "call_drop_refs: dropping %d in refs\n", vi->ninii );
822 		printf( "call_drop_refs: dropping %d out refs\n", vi->noutii );
823 #endif /*DEBUG*/
824 
825 		for( i = 0; i < vi->ninii; i++ )
826 			managed_destroy_nonheap( MANAGED( vi->inii[i] ) );
827 		for( i = 0; i < vi->noutii; i++ )
828 			managed_destroy_nonheap( MANAGED( vi->outii[i] ) );
829 
830 		vi->must_drop = FALSE;
831 	}
832 }
833 
834 static void
call_info_dispose(GObject * gobject)835 call_info_dispose( GObject *gobject )
836 {
837 	CallInfo *vi;
838 
839 	g_return_if_fail( gobject != NULL );
840 	g_return_if_fail( IS_CALL_INFO( gobject ) );
841 
842 	vi = CALL_INFO( gobject );
843 
844 #ifdef DEBUG
845 	printf( "call_info_dispose: (%p) %s \"%s\"\n",
846 		vi, G_OBJECT_TYPE_NAME( vi ), vi->name );
847 #endif /*DEBUG*/
848 
849 	/* Are we in the history? Remove us.
850 	 */
851 	cache_history_remove( vi );
852 
853 	/* Drop any refs we may have left dangling.
854 	 */
855 	call_drop_refs( vi );
856 
857 	G_OBJECT_CLASS( parent_class )->dispose( gobject );
858 }
859 
860 /* Junk stuff we may have attached to vargv.
861  */
862 static void
call_vargv_free(im_function * fn,im_object * vargv)863 call_vargv_free( im_function *fn, im_object *vargv )
864 {
865 	int i;
866 
867 	/* Free any CALL args we built and haven't used.
868 	 */
869 	for( i = 0; i < fn->argc; i++ ) {
870 		im_type_desc *ty = fn->argv[i].desc;
871 		im_object *obj = vargv[i];
872 		CallArgumentType vt;
873 
874 		/* Make sure we don't damage any error message we might
875 		 * have.
876 		 */
877 		error_block();
878 		vt = call_lookup_type( ty->type );
879 		error_unblock();
880 
881 		switch( vt ) {
882 		case CALL_NONE:		/* IM_TYPE_DISPLAY */
883 		case CALL_DOUBLE:
884 		case CALL_INT:
885 		case CALL_COMPLEX:
886 		case CALL_GVALUE:
887 		case CALL_INTERPOLATE:
888 		case CALL_IMAGE:
889 			/* Do nothing.
890 			 */
891 			break;
892 
893 		case CALL_STRING:
894 			IM_FREE( obj );
895 			break;
896 
897 		case CALL_IMAGEVEC:
898 			IM_FREE( ((im_imagevec_object *) obj)->vec );
899 			break;
900 
901 		case CALL_DOUBLEVEC:
902 			IM_FREE( ((im_doublevec_object *) obj)->vec );
903 			break;
904 
905 		case CALL_INTVEC:
906 			IM_FREE( ((im_intvec_object *) obj)->vec );
907 			break;
908 
909 		case CALL_DMASK:
910 			IM_FREE( ((im_mask_object *) obj)->name );
911 			IM_FREEF( im_free_dmask,
912 				((im_mask_object *) obj)->mask );
913 			break;
914 
915 		case CALL_IMASK:
916 			IM_FREE( ((im_mask_object *) obj)->name );
917 			IM_FREEF( im_free_imask,
918 				((im_mask_object *) obj)->mask );
919 			break;
920 
921 		default:
922 			g_assert( FALSE );
923 		}
924 	}
925 }
926 
927 static void
call_info_finalize(GObject * gobject)928 call_info_finalize( GObject *gobject )
929 {
930 	CallInfo *vi;
931 
932 	g_return_if_fail( gobject != NULL );
933 	g_return_if_fail( IS_CALL_INFO( gobject ) );
934 
935 	vi = CALL_INFO( gobject );
936 
937 #ifdef DEBUG_LEAK
938 	call_info_all = g_slist_remove( call_info_all, vi );
939 #endif /*DEBUG_LEAK*/
940 
941 	if( vi->vargv ) {
942 		call_vargv_free( vi->fn, vi->vargv );
943 		im_free_vargv( vi->fn, vi->vargv );
944 		IM_FREE( vi->vargv );
945 	}
946 
947 	G_OBJECT_CLASS( parent_class )->finalize( gobject );
948 }
949 
950 static void
call_info_info(iObject * iobject,VipsBuf * buf)951 call_info_info( iObject *iobject, VipsBuf *buf )
952 {
953 	CallInfo *vi = CALL_INFO( iobject );
954 
955 	vips_buf_appendf( buf, "call_info_info: (%p) %s \"%s\"\n",
956 		vi, G_OBJECT_TYPE_NAME( vi ), NN( IOBJECT( vi )->name ) );
957 }
958 
959 static void
call_info_class_init(CallInfoClass * class)960 call_info_class_init( CallInfoClass *class )
961 {
962 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
963 	iObjectClass *iobject_class = IOBJECT_CLASS( class );
964 
965 	parent_class = g_type_class_peek_parent( class );
966 
967 	gobject_class->dispose = call_info_dispose;
968 	gobject_class->finalize = call_info_finalize;
969 
970 	iobject_class->info = call_info_info;
971 }
972 
973 static void
call_info_init(CallInfo * vi)974 call_info_init( CallInfo *vi )
975 {
976 	int i;
977 
978 	vi->name = NULL;
979 	vi->fn = NULL;
980 	vi->rc = NULL;
981 	vi->vargv = NULL;
982 	vi->nargs = 0;
983 	vi->nres = 0;
984 	vi->nires = 0;
985 	vi->ninii = 0;
986 	vi->noutii = 0;
987 	vi->use_lut = FALSE;		/* Set this properly later */
988 	vi->found_hash = FALSE;
989 	vi->in_cache = FALSE;
990 	vi->must_drop = FALSE;
991 
992 #ifdef DEBUG_LEAK
993 	call_info_all = g_slist_prepend( call_info_all, vi );
994 #endif /*DEBUG_LEAK*/
995 
996 	for( i = 0; i < MAX_CALL_ARGS; i++ ) {
997 		vi->outii_destroy_sid[i] = 0;
998 		vi->inii_destroy_sid[i] = 0;
999 		vi->inii_invalidate_sid[i] = 0;
1000 	}
1001 }
1002 
1003 GType
call_info_get_type(void)1004 call_info_get_type( void )
1005 {
1006 	static GType type = 0;
1007 
1008 	if( !type ) {
1009 		static const GTypeInfo info = {
1010 			sizeof( CallInfoClass ),
1011 			NULL,           /* base_init */
1012 			NULL,           /* base_finalize */
1013 			(GClassInitFunc) call_info_class_init,
1014 			NULL,           /* class_finalize */
1015 			NULL,           /* class_data */
1016 			sizeof( CallInfo ),
1017 			32,             /* n_preallocs */
1018 			(GInstanceInitFunc) call_info_init,
1019 		};
1020 
1021 		type = g_type_register_static( TYPE_IOBJECT,
1022 			"CallInfo", &info, 0 );
1023 	}
1024 
1025 	return( type );
1026 }
1027 
1028 static CallInfo *
call_new(Reduce * rc,im_function * fn)1029 call_new( Reduce *rc, im_function *fn )
1030 {
1031 	CallInfo *vi;
1032 	int i;
1033 
1034 	g_assert( fn->argc < MAX_CALL_ARGS - 1 );
1035 
1036 	if( !fn ||
1037 		!(vi = CALL_INFO( g_object_new( TYPE_CALL_INFO, NULL ) )) )
1038 		return( NULL );
1039 	vi->name = fn->name;
1040 	vi->fn = fn;
1041 	vi->rc = rc;
1042 
1043 	/* Look over the args ... count the number of inputs we need, and
1044 	 * the number of outputs we generate. Note the position of each.
1045 	 */
1046 	for( i = 0; i < vi->fn->argc; i++ ) {
1047 		im_type_desc *ty = vi->fn->argv[i].desc;
1048 
1049 		if( call_type_makes_output( ty ) ) {
1050 			vi->outpos[vi->nres] = i;
1051 			vi->nres += 1;
1052 
1053 			/* Image output.
1054 			 */
1055 			if( strcmp( ty->type, IM_TYPE_IMAGE ) == 0 )
1056 				vi->nires += 1;
1057 		}
1058 
1059 		if( call_type_needs_input( ty ) ) {
1060 			vi->inpos[vi->nargs] = i;
1061 			vi->nargs += 1;
1062 		}
1063 	}
1064 
1065 	/* Make the call spine, alloc memory.
1066 	 */
1067 	if( !(vi->vargv = IM_ARRAY( NULL, vi->fn->argc + 1, im_object )) ||
1068 		im_allocate_vargv( vi->fn, vi->vargv ) ) {
1069 		call_error( vi );
1070 		g_object_unref( vi );
1071 		return( NULL );
1072 	}
1073 
1074 	return( vi );
1075 }
1076 
1077 /* Add another ii to outii.
1078  */
1079 static gboolean
call_add_output_ii(CallInfo * vi,Imageinfo * ii)1080 call_add_output_ii( CallInfo *vi, Imageinfo *ii )
1081 {
1082 	if( vi->noutii > MAX_CALL_ARGS ) {
1083 		call_error_toomany( vi );
1084 		return( FALSE );
1085 	}
1086 
1087 	vi->outii[vi->noutii] = ii;
1088 	vi->noutii += 1;
1089 
1090 	/* We hold a ref to the ii until the call is done and the result
1091 	 * written back to nip2. If we cache the result, we make a new
1092 	 * weakref.
1093 	 */
1094 	managed_dup_nonheap( MANAGED( ii ) );
1095 	vi->must_drop = TRUE;
1096 
1097 	return( TRUE );
1098 }
1099 
1100 /* Init an output slot in vargv.
1101  */
1102 static gboolean
call_build_output(CallInfo * vi,int i)1103 call_build_output( CallInfo *vi, int i )
1104 {
1105 	im_type_desc *ty = vi->fn->argv[i].desc;
1106 
1107 	/* Provide output objects for the function to write to.
1108 	 */
1109 	switch( call_lookup_type( ty->type ) ) {
1110 	case CALL_DOUBLE:
1111 	case CALL_INT:
1112 	case CALL_COMPLEX:
1113 	case CALL_STRING:
1114 		break;
1115 
1116 	case CALL_IMAGE:
1117 {
1118 		Imageinfo *ii;
1119 
1120 		if( !(ii = imageinfo_new_temp( main_imageinfogroup,
1121 			vi->rc->heap, NULL, "p" )) ||
1122 			!call_add_output_ii( vi, ii ) ||
1123 			!(vi->vargv[i] = imageinfo_get( FALSE, ii )) )
1124 			return( FALSE );
1125 
1126 		break;
1127 }
1128 
1129 	case CALL_DMASK:
1130 	case CALL_IMASK:
1131 	{
1132 		im_mask_object *mo = vi->vargv[i];
1133 
1134 		mo->mask = NULL;
1135 		mo->name = im_strdup( NULL, "" );
1136 
1137 		break;
1138 	}
1139 
1140 	case CALL_GVALUE:
1141 	{
1142 		GValue *value = vi->vargv[i];
1143 
1144 		memset( value, 0, sizeof( GValue ) );
1145 
1146 		break;
1147 	}
1148 
1149 	case CALL_DOUBLEVEC:
1150 	case CALL_INTVEC:
1151 	{
1152 		/* intvec is also int + pointer.
1153 		 */
1154 		im_doublevec_object *dv = vi->vargv[i];
1155 
1156 		dv->n = 0;
1157 		dv->vec = NULL;
1158 
1159 		break;
1160 	}
1161 
1162 	default:
1163 		g_assert( FALSE );
1164 	}
1165 
1166 	return( TRUE );
1167 }
1168 
1169 static gboolean
call_build_inputva(CallInfo * vi,int i,va_list * ap)1170 call_build_inputva( CallInfo *vi, int i, va_list *ap )
1171 {
1172 	im_type_desc *ty = vi->fn->argv[i].desc;
1173 
1174 	switch( call_lookup_type( ty->type ) ) {
1175 	case CALL_DOUBLE:
1176 	{
1177 		double v = va_arg( *ap, double );
1178 
1179 #ifdef DEBUG
1180 		printf( "%g\n", v );
1181 #endif /*DEBUG*/
1182 
1183 		*((double*)vi->vargv[i]) = v;
1184 
1185 		if( trace_flags & TRACE_VIPS )
1186 			vips_buf_appendf( trace_current(), "%g ", v );
1187 
1188 		break;
1189 	}
1190 
1191 	case CALL_INT:
1192 	{
1193 		int v = va_arg( *ap, int );
1194 
1195 #ifdef DEBUG
1196 		printf( "%d\n", v );
1197 #endif /*DEBUG*/
1198 
1199 		*((int*)vi->vargv[i]) = v;
1200 
1201 		if( trace_flags & TRACE_VIPS )
1202 			vips_buf_appendf( trace_current(), "%d ", v );
1203 
1204 		break;
1205 	}
1206 
1207 	case CALL_GVALUE:
1208 	{
1209 		GValue *value = va_arg( *ap, GValue * );
1210 
1211 #ifdef DEBUG
1212 		printf( "gvalue %p\n", value );
1213 #endif /*DEBUG*/
1214 
1215 		vi->vargv[i] = value;
1216 
1217 		if( trace_flags & TRACE_VIPS ) {
1218 			vips_buf_appendgv( trace_current(), value );
1219 			vips_buf_appends( trace_current(), " " );
1220 		}
1221 
1222 		break;
1223 	}
1224 
1225 	case CALL_INTERPOLATE:
1226 	{
1227 		VipsInterpolate *value =
1228 			va_arg( *ap, VipsInterpolate * );
1229 
1230 #ifdef DEBUG
1231 		printf( "interpolate %p\n", value );
1232 #endif /*DEBUG*/
1233 
1234 		vi->vargv[i] = value;
1235 
1236 		if( trace_flags & TRACE_VIPS ) {
1237 			vips_object_to_string( VIPS_OBJECT( value ),
1238 				trace_current() );
1239 			vips_buf_appends( trace_current(), " " );
1240 		}
1241 
1242 		break;
1243 	}
1244 
1245 	case CALL_IMAGE:
1246 	{
1247 		Imageinfo *ii = va_arg( *ap, Imageinfo * );
1248 
1249 #ifdef DEBUG
1250 		printf( "imageinfo %p\n", ii );
1251 #endif /*DEBUG*/
1252 
1253 		if( !call_add_input_ii( vi, ii ) )
1254 			return( FALSE );
1255 
1256 		/* Filled in later.
1257 		 */
1258 		vi->vargv[i] = NULL;
1259 
1260 		if( trace_flags & TRACE_VIPS ) {
1261 			VipsBuf *buf = trace_current();
1262 
1263 			if( ii && ii->im ) {
1264 				vips_buf_appends( buf, "<" );
1265 				vips_buf_appendf( buf,
1266 					_( "image \"%s\"" ),
1267 					ii->im->filename );
1268 				vips_buf_appends( buf, "> " );
1269 			}
1270 			else {
1271 				vips_buf_appends( buf, "<" );
1272 				vips_buf_appends( buf,
1273 					_( "no image" ) );
1274 				vips_buf_appends( buf, "> " );
1275 			}
1276 		}
1277 
1278 		break;
1279 	}
1280 
1281 	case CALL_DOUBLEVEC:
1282 	{
1283 		int n = va_arg( *ap, int );
1284 		double *vec = va_arg( *ap, double * );
1285 
1286 #ifdef DEBUG
1287 {
1288 		int i;
1289 
1290 		for( i = 0; i < n; i++ )
1291 			printf( "%g, ", vec[i] );
1292 		printf( "\n" );
1293 }
1294 #endif /*DEBUG*/
1295 
1296 		if( call_make_doublevec( vi->vargv[i], n, vec ) )
1297 			return( FALSE );
1298 
1299 		if( trace_flags & TRACE_VIPS ) {
1300 			VipsBuf *buf = trace_current();
1301 			int i;
1302 
1303 			vips_buf_appendf( buf, "<" );
1304 			vips_buf_appendf( buf, _( "doublevec" ) );
1305 			for( i = 0; i < n; i++ )
1306 				vips_buf_appendf( buf, " %g", vec[i] );
1307 			vips_buf_appends( buf, "> " );
1308 		}
1309 
1310 		break;
1311 	}
1312 
1313 	/*
1314 
1315 		FIXME ... add intvec perhaps
1316 
1317 	 */
1318 
1319 	case CALL_IMAGEVEC:
1320 	{
1321 		int n = va_arg( *ap, int );
1322 		Imageinfo **vec = va_arg( *ap, Imageinfo ** );
1323 
1324 #ifdef DEBUG
1325 {
1326 		int i;
1327 
1328 		for( i = 0; i < n; i++ )
1329 			printf( "%p, ", vec[i] );
1330 		printf( "\n" );
1331 }
1332 #endif /*DEBUG*/
1333 
1334 		if( call_make_imagevec( vi->vargv[i], n ) )
1335 			return( FALSE );
1336 
1337 		for( i = 0; i < n; i++ )
1338 			if( !call_add_input_ii( vi, vec[i] ) )
1339 				return( FALSE );
1340 
1341 		if( trace_flags & TRACE_VIPS ) {
1342 			VipsBuf *buf = trace_current();
1343 			int i;
1344 
1345 			vips_buf_appendf( buf, "<" );
1346 			vips_buf_appendf( buf, _( "imagevec" ) );
1347 			for( i = 0; i < n; i++ ) {
1348 				vips_buf_appendf( buf, " <" );
1349 				vips_buf_appendf( buf,
1350 					_( "image \"%s\"" ),
1351 					vec[i]->im->filename );
1352 				vips_buf_appendf( buf, ">" );
1353 			}
1354 			vips_buf_appends( buf, "> " );
1355 		}
1356 
1357 		break;
1358 	}
1359 
1360 	default:
1361 		g_assert( FALSE );
1362 	}
1363 
1364 	return( TRUE );
1365 }
1366 
1367 /* Fill an argument vector from the C stack.
1368  */
1369 static gboolean
call_fillva(CallInfo * vi,va_list * ap)1370 call_fillva( CallInfo *vi, va_list *ap )
1371 {
1372 	int i;
1373 
1374 	g_assert( vi->ninii == 0 );
1375 	g_assert( vi->noutii == 0 );
1376 
1377 	for( i = 0; i < vi->fn->argc; i++ ) {
1378 		im_type_desc *ty = vi->fn->argv[i].desc;
1379 
1380 #ifdef DEBUG
1381 		printf( "call_fillva: arg[%d] (%s) = ", i, ty->type );
1382 #endif /*DEBUG*/
1383 
1384 		if( call_type_makes_output( ty ) ) {
1385 			if( !call_build_output( vi, i ) )
1386 				return( FALSE );
1387 #ifdef DEBUG
1388 			printf( " output\n" );
1389 #endif /*DEBUG*/
1390 		}
1391 
1392 		if( strcmp( ty->type, IM_TYPE_DISPLAY ) == 0 ) {
1393 			/* DISPLAY argument ... just IM_TYPE_sRGB.
1394 			 */
1395 			vi->vargv[i] = im_col_displays( 7 );
1396 
1397 #ifdef DEBUG
1398 			printf( " display\n" );
1399 #endif /*DEBUG*/
1400 		}
1401 
1402 		if( call_type_needs_input( ty ) ) {
1403 			if( !call_build_inputva( vi, i, ap ) )
1404 				return( FALSE );
1405 		}
1406 	}
1407 
1408 	/* Every output ii depends upon all of the input ii.
1409 	 */
1410 	for( i = 0; i < vi->noutii; i++ )
1411 		managed_sub_add_all( MANAGED( vi->outii[i] ),
1412 			vi->ninii, (Managed **) vi->inii );
1413 
1414 #ifdef DEBUG
1415 	printf( "call_fill_spine: reffed %d in\n", vi->ninii );
1416 	printf( "call_fill_spine: created %d out\n", vi->noutii );
1417 #endif /*DEBUG*/
1418 
1419 	return( TRUE );
1420 }
1421 
1422 static gboolean
callva_sub(Reduce * rc,const char * name,PElement * out,va_list * ap)1423 callva_sub( Reduce *rc, const char *name, PElement *out, va_list *ap )
1424 {
1425 	CallInfo *vi;
1426 	gboolean result;
1427 
1428 	if( trace_flags & TRACE_VIPS )
1429 		trace_push();
1430 
1431 	if( !(vi = call_new( rc, im_find_function( name ) )) )
1432 		return( FALSE );
1433 
1434 	if( trace_flags & TRACE_VIPS )
1435 		vips_buf_appendf( trace_current(), "\"%s\" ", vi->name );
1436 
1437 	result = TRUE;
1438 
1439 	if( !call_fillva( vi, ap ) )
1440 		result = FALSE;
1441 
1442 	if( trace_flags & TRACE_VIPS )
1443 		vips_buf_appends( trace_current(), " ->\n" );
1444 
1445 	if( result && (
1446 		!(vi = cache_dispatch( vi, out )) ||
1447 		!call_write_result( vi, out ) ) )
1448 		result = FALSE;
1449 
1450 	if( trace_flags & TRACE_VIPS ) {
1451 		trace_result( TRACE_VIPS, out );
1452 		trace_pop();
1453 	}
1454 
1455 	if( vi ) {
1456 		/* We must drop refs explicitly, since this unref might not
1457 		 * dispose the vi.
1458 		 */
1459 		call_drop_refs( vi );
1460 
1461 		g_object_unref( vi );
1462 	}
1463 
1464 	return( result );
1465 }
1466 
1467 /* Call a CALL function picking up args from the function call.
1468  */
1469 void
callva(Reduce * rc,PElement * out,const char * name,...)1470 callva( Reduce *rc, PElement *out, const char *name, ... )
1471 {
1472 	va_list ap;
1473 	gboolean result;
1474 
1475 #ifdef DEBUG
1476 	printf( "** callva: starting for %s\n", name );
1477 #endif /*DEBUG*/
1478 
1479         va_start( ap, name );
1480 	result = callva_sub( rc, name, out, &ap );
1481         va_end( ap );
1482 
1483 #ifdef DEBUG
1484 	printf( "callva: done\n" );
1485 #endif /*DEBUG*/
1486 
1487 	if( !result )
1488 		reduce_throw( rc );
1489 }
1490 
1491 /* Fill an argument vector from our stack frame. Number of args already
1492  * checked.
1493  */
1494 static gboolean
call_fill_spine(CallInfo * vi,HeapNode ** arg)1495 call_fill_spine( CallInfo *vi, HeapNode **arg )
1496 {
1497 	int i, j;
1498 
1499 	g_assert( vi->ninii == 0 );
1500 	g_assert( vi->noutii == 0 );
1501 
1502 	/* Fully reduce all arguments. Once we've done this, we can be sure
1503 	 * there will not be a GC while we gather, and therefore that no
1504 	 * pointers will become invalid during this call.
1505 	 */
1506 	for( i = 0; i < vi->nargs; i++ ) {
1507 		PElement rhs;
1508 
1509 		PEPOINTRIGHT( arg[i], &rhs );
1510 		if( !heap_reduce_strict( &rhs ) )
1511 			return( FALSE );
1512 	}
1513 
1514 	for( j = 0, i = 0; i < vi->fn->argc; i++ ) {
1515 		im_type_desc *ty = vi->fn->argv[i].desc;
1516 
1517 		if( call_type_makes_output( ty ) )
1518 			if( !call_build_output( vi, i ) )
1519 				return( FALSE );
1520 
1521 		if( strcmp( ty->type, IM_TYPE_DISPLAY ) == 0 ) {
1522 			/* Special DISPLAY argument - don't fetch another ip
1523 			 * argument for it.
1524 			 */
1525 			(void) call_fromip( vi, i, NULL );
1526 		}
1527 
1528 		if( call_type_needs_input( ty ) ) {
1529 			PElement rhs;
1530 
1531 			/* Convert ip type to CALL type.
1532 			 */
1533 			PEPOINTRIGHT( arg[vi->nargs - j - 1], &rhs );
1534 			if( !call_fromip( vi, i, &rhs ) ) {
1535 				call_error_arg( vi, arg, j );
1536 				return( FALSE );
1537 			}
1538 
1539 			j += 1;
1540 		}
1541 	}
1542 
1543 	/* Every output ii depends upon all of the input ii.
1544 	 */
1545 	for( i = 0; i < vi->noutii; i++ )
1546 		managed_sub_add_all( MANAGED( vi->outii[i] ),
1547 			vi->ninii, (Managed **) vi->inii );
1548 
1549 #ifdef DEBUG
1550 	printf( "call_fill_spine: reffed %d inii\n", vi->ninii );
1551 	printf( "call_fill_spine: created %d outii\n", vi->noutii );
1552 #endif /*DEBUG*/
1553 
1554 	return( TRUE );
1555 }
1556 
1557 static gboolean
call_spine_sub(Reduce * rc,const char * name,im_function * fn,PElement * out,HeapNode ** arg)1558 call_spine_sub( Reduce *rc, const char *name, im_function *fn,
1559 	PElement *out, HeapNode **arg )
1560 {
1561 	CallInfo *vi;
1562 	gboolean result;
1563 
1564 #ifdef DEBUG
1565 	printf( "** call_spine: starting for %s\n", name );
1566 #endif /*DEBUG*/
1567 
1568 	if( !(vi = call_new( rc, fn )) )
1569 		return( FALSE );
1570 
1571 	if( trace_flags & TRACE_VIPS ) {
1572 		VipsBuf *buf = trace_push();
1573 
1574 		vips_buf_appendf( buf, "\"%s\" ", name );
1575 		trace_args( arg, vi->nargs );
1576 	}
1577 
1578 	result = TRUE;
1579 
1580 	if( !call_fill_spine( vi, arg ) ||
1581 		!(vi = cache_dispatch( vi, out )) ||
1582 		!call_write_result( vi, out ) )
1583 		result = FALSE;
1584 
1585 	if( trace_flags & TRACE_VIPS ) {
1586 		trace_result( TRACE_VIPS, out );
1587 		trace_pop();
1588 	}
1589 
1590 	if( vi ) {
1591 		/* We must drop refs explicitly, since this unref might not
1592 		 * dispose the vi.
1593 		 */
1594 		call_drop_refs( vi );
1595 
1596 		g_object_unref( vi );
1597 	}
1598 
1599 #ifdef DEBUG
1600 	printf( "call_spine: done\n" );
1601 #endif /*DEBUG*/
1602 
1603 	return( result );
1604 }
1605 
1606 /* Call a CALL function, pick up args from the graph.
1607  */
1608 void
call_spine(Reduce * rc,const char * name,HeapNode ** arg,PElement * out)1609 call_spine( Reduce *rc, const char *name, HeapNode **arg, PElement *out )
1610 {
1611 	if( !call_spine_sub( rc, name, im_find_function( name ), out, arg ) )
1612 		reduce_throw( rc );
1613 }
1614 
1615 /* As an ActionFn.
1616  */
1617 void
call_run(Reduce * rc,Compile * compile,int op,const char * name,HeapNode ** arg,PElement * out,im_function * function)1618 call_run( Reduce *rc, Compile *compile,
1619 	int op, const char *name, HeapNode **arg, PElement *out,
1620 	im_function *function )
1621 {
1622 	if( !call_spine_sub( rc, name, function, out, arg ) )
1623 		reduce_throw( rc );
1624 }
1625