1
/* Call vips functions, cache recent results
6
Copyright (C) 1991-2003 The National Gallery
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.
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.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
34
#define DEBUG_HISTORY_SANITY
35
#define DEBUG_HISTORY_MISS
40
/* This is usually turned on from a -D in cflags.
44
/* Often want it off ... we get spurious complaints about leaks if an
45
* operation has no images in or out (eg. im_version) because it'll never
50
/* The previous function calls we are caching, plus an LRU queue for flushing.
52
static GHashTable *vips_history_table = NULL;
53
static Queue *vips_history_lru = NULL;
54
int vips_history_size = 0;
56
/* Hash from a vargv ... just look at input args and the function name.
59
vips_hash( VipsInfo *vi )
69
/* add ints, floats, pointers and strings to the hash.
71
FIXME ... could do better on double? could or top and bottom 32 bits
72
but would this be stupid on a 64 bit machine?
75
#define HASH_I( I ) hash = (hash << 1) | ((unsigned int) (I));
76
#define HASH_D( D ) hash = (hash << 1) | ((unsigned int) (D));
77
#define HASH_P( P ) hash = (hash << 1) | (GPOINTER_TO_UINT( P ));
78
#define HASH_S( S ) hash = (hash << 1) | g_str_hash( S );
80
/* Add the function to the hash. We often call many functions on
81
* the same args, we'd like these calls to hash to different numbers.
85
for( i = 0; i < vi->fn->argc; i++ ) {
86
im_type_desc *ty = vi->fn->argv[i].desc;
88
if( vips_type_needs_input( ty ) ) {
89
switch( vips_lookup_type( ty->type ) ) {
91
HASH_D( *((double *) vi->vargv[i]) );
95
HASH_I( *((int *) vi->vargv[i]) );
99
HASH_D( ((double *) vi->vargv[i])[0] );
100
HASH_D( ((double *) vi->vargv[i])[1] );
104
HASH_S( (char *) vi->vargv[i] );
108
case VIPS_INTERPOLATE:
113
im_doublevec_object *v =
114
(im_doublevec_object *) vi->vargv[i];
117
for( j = 0; j < v->n; j++ )
125
im_intvec_object *v =
126
(im_intvec_object *) vi->vargv[i];
129
for( j = 0; j < v->n; j++ )
137
im_mask_object *mo = vi->vargv[i];
138
DOUBLEMASK *mask = mo->mask;
140
/* mask can be NULL if we are called after
141
* vips_new() but before we've built the arg
145
int ne = mask->xsize * mask->ysize;
148
for( j = 0; j < ne; j++ )
149
HASH_D( mask->coeff[j] );
150
HASH_D( mask->scale );
151
HASH_D( mask->offset );
159
im_mask_object *mo = vi->vargv[i];
160
INTMASK *mask = mo->mask;
162
/* mask can be NULL if we are called after
163
* vips_new() but before we've built the arg
167
int ne = mask->xsize * mask->ysize;
170
for( j = 0; j < ne; j++ )
171
HASH_I( mask->coeff[j] );
172
HASH_I( mask->scale );
173
HASH_I( mask->offset );
186
/* And the input images.
188
for( i = 0; i < vi->ninii; i++ )
189
HASH_P( vi->inii[i] );
191
vi->found_hash = TRUE;
197
/* Are two function calls equal. Check the func and the input args.
200
vips_equal( VipsInfo *vi1, VipsInfo *vi2 )
203
im_function *fn = vi1->fn;
208
if( vi1->fn != vi2->fn )
211
for( i = 0; i < fn->argc; i++ ) {
212
im_type_desc *ty = fn->argv[i].desc;
214
if( vips_type_needs_input( ty ) ) {
215
switch( vips_lookup_type( ty->type ) ) {
217
if( *((double *) vi1->vargv[i]) !=
218
*((double *) vi2->vargv[i]) )
223
if( *((int *) vi1->vargv[i]) !=
224
*((int *) vi2->vargv[i]) )
229
if( ((double *) vi1->vargv[i])[0] !=
230
((double *) vi2->vargv[i])[0] )
232
if( ((double *) vi1->vargv[i])[1] !=
233
((double *) vi2->vargv[i])[1] )
238
if( strcmp( (char *) vi1->vargv[i],
239
(char *) vi2->vargv[i] ) != 0 )
245
im_doublevec_object *v1 =
246
(im_doublevec_object *) vi1->vargv[i];
247
im_doublevec_object *v2 =
248
(im_doublevec_object *) vi2->vargv[i];
251
for( j = 0; j < v1->n; j++ )
252
if( v1->vec[j] != v2->vec[j] )
260
im_intvec_object *v1 =
261
(im_intvec_object *) vi1->vargv[i];
262
im_intvec_object *v2 =
263
(im_intvec_object *) vi2->vargv[i];
266
for( j = 0; j < v1->n; j++ )
267
if( v1->vec[j] != v2->vec[j] )
275
im_mask_object *mo1 =
276
(im_mask_object *) vi1->vargv[i];
277
im_mask_object *mo2 =
278
(im_mask_object *) vi2->vargv[i];
279
DOUBLEMASK *mask1 = mo1->mask;
280
DOUBLEMASK *mask2 = mo2->mask;
281
int ne = mask1->xsize * mask2->ysize;
284
if( mask1->xsize != mask2->xsize ||
285
mask1->ysize != mask2->ysize )
288
for( j = 0; j < ne; j++ )
289
if( mask1->coeff[j] != mask2->coeff[j] )
292
if( mask1->scale != mask2->scale )
294
if( mask1->offset != mask2->offset )
302
im_mask_object *mo1 =
303
(im_mask_object *) vi1->vargv[i];
304
im_mask_object *mo2 =
305
(im_mask_object *) vi2->vargv[i];
306
INTMASK *mask1 = mo1->mask;
307
INTMASK *mask2 = mo2->mask;
308
int ne = mask1->xsize * mask2->ysize;
311
if( mask1->xsize != mask2->xsize ||
312
mask1->ysize != mask2->ysize )
315
for( j = 0; j < ne; j++ )
316
if( mask1->coeff[j] != mask2->coeff[j] )
319
if( mask1->scale != mask2->scale )
321
if( mask1->offset != mask2->offset )
329
im_imagevec_object *v1 =
330
(im_imagevec_object *) vi1->vargv[i];
331
im_imagevec_object *v2 =
332
(im_imagevec_object *) vi2->vargv[i];
340
/* Very strict. Could be more generous here: we'd need
341
* to have a pspec for each argument type and then use
342
* g_param_values_cmp() to test equality.
345
if( vi1->vargv[i] != vi2->vargv[i] )
349
case VIPS_INTERPOLATE:
350
if( vi1->vargv[i] != vi2->vargv[i] )
361
/* And the input images.
363
if( vi1->ninii != vi2->ninii )
365
for( i = 0; i < vi1->ninii; i++ )
366
if( vi1->inii[i] != vi2->inii[i] )
372
#ifdef DEBUG_HISTORY_SANITY
374
vips_history_sanity_sub( VipsInfo *vi )
376
g_assert( g_slist_find( vips_history_lru->list, vi ) );
380
vips_history_sanity( void )
384
if( !vips_history_lru || !vips_history_table )
387
/* Everything that's on the LRU should be in the history table.
389
for( p = vips_history_lru->list; p; p = p->next ) {
390
VipsInfo *vi = (VipsInfo *) p->data;
392
g_assert( g_hash_table_lookup( vips_history_table, vi ) );
395
g_assert( vi->fn->argc > 0 && vi->fn->argc < MAX_VIPS_ARGS );
396
g_assert( vi->in_cache );
399
/* Everything that's on the history table should be in the LRU.
401
g_hash_table_foreach( vips_history_table,
402
(GHFunc) vips_history_sanity_sub, NULL );
404
/* Everything that's on the LRU should be in the global vips_info
407
for( p = vips_history_lru->list; p; p = p->next ) {
408
VipsInfo *vi = (VipsInfo *) p->data;
410
/* Need to build with DEBUG on before vips_info_all is
413
g_assert( g_slist_find( vips_info_all, vi ) );
416
/* Everything on vips_info_all that's not in vips_history_table should
417
* have in_cache FALSE.
419
for( p = vips_info_all; p; p = p->next ) {
420
VipsInfo *vi = (VipsInfo *) p->data;
422
if( !g_hash_table_lookup( vips_history_table, vi ) )
423
g_assert( !vi->in_cache );
426
/* Every input image argument on every in-cache call should be sane.
428
for( p = vips_info_all; p; p = p->next ) {
429
VipsInfo *vi = (VipsInfo *) p->data;
435
for( i = 0; i < vi->fn->argc; i++ ) {
436
im_type_desc *ty = vi->fn->argv[i].desc;
438
if( !vips_type_needs_input( ty ) )
441
if( strcmp( ty->type, IM_TYPE_IMAGE ) == 0 ) {
442
IMAGE *im = (IMAGE *) vi->vargv[i];
444
g_assert( !im_image_sanity( im ) );
446
else if( strcmp( ty->type, IM_TYPE_IMAGEVEC ) == 0 ) {
447
im_imagevec_object *iv =
448
(im_imagevec_object *) vi->vargv[i];
451
for( j = 0; j < iv->n; j++)
452
g_assert( !im_image_sanity(
458
/* All the output images should be sane.
460
for( p = vips_info_all; p; p = p->next ) {
461
VipsInfo *vi = (VipsInfo *) p->data;
467
for( i = 0; i < vi->noutii; i++ ) {
470
if( (im = imageinfo_get( FALSE, vi->outii[i] )) )
471
g_assert( !im_image_sanity( im ) );
475
#endif /*DEBUG_HISTORY_SANITY */
477
/* Is a function call in our history? Return the old one.
480
vips_history_lookup( VipsInfo *vi )
484
if( !vips_history_table ) {
485
vips_history_table = g_hash_table_new(
486
(GHashFunc) vips_hash, (GEqualFunc) vips_equal );
487
vips_history_lru = queue_new();
490
old_vi = (VipsInfo *) g_hash_table_lookup( vips_history_table, vi );
494
printf( "vips_history_lookup: found \"%s\"\n", old_vi->name );
495
#endif /*DEBUG_HISTORY*/
496
#ifdef DEBUG_HISTORY_SANITY
497
vips_history_sanity();
498
#endif /*DEBUG_HISTORY_SANITY*/
503
/* Bump to end of LRU.
506
vips_history_touch( VipsInfo *vi )
508
g_assert( vi->in_cache );
510
queue_remove( vips_history_lru, vi );
511
queue_add( vips_history_lru, vi );
513
#ifdef DEBUG_HISTORY_SANITY
514
vips_history_sanity();
515
#endif /*DEBUG_HISTORY_SANITY*/
517
printf( "vips_history_touch: bumping \"%s\"\n", vi->name );
518
#endif /*DEBUG_HISTORY*/
521
/* Are we in the history? Remove us. Called from vips_info_dispose() on unref,
522
* don't call this directly.
525
vips_history_remove( VipsInfo *vi )
530
queue_remove( vips_history_lru, vi );
531
g_hash_table_remove( vips_history_table, vi );
532
vips_history_size -= 1;
533
vi->in_cache = FALSE;
536
printf( "vips_history_remove: removing \"%s\"\n", vi->name );
537
#endif /*DEBUG_HISTORY*/
540
/* Disconnect signals.
542
for( i = 0; i < vi->noutii; i++ )
543
FREESID( vi->outii_destroy_sid[i], vi->outii[i] );
544
for( i = 0; i < vi->ninii; i++ ) {
545
FREESID( vi->inii_destroy_sid[i], vi->inii[i] );
546
FREESID( vi->inii_invalidate_sid[i], vi->inii[i] );
549
#ifdef DEBUG_HISTORY_SANITY
550
vips_history_sanity();
551
#endif /*DEBUG_HISTORY_SANITY*/
555
vips_history_remove_lru( void )
559
vi = (VipsInfo *) queue_head( vips_history_lru );
562
printf( "vips_history_remove_lru: flushing \"%s\"\n", vi->name );
563
#endif /*DEBUG_HISTORY*/
565
g_object_unref( vi );
567
#ifdef DEBUG_HISTORY_SANITY
568
vips_history_sanity();
569
#endif /*DEBUG_HISTORY_SANITY*/
573
vips_history_destroy_cb( Imageinfo *ii, VipsInfo *vi )
576
printf( "vips_history_destroy_cb: on death of ii, uncaching \"%s\"\n",
578
#endif /*DEBUG_HISTORY*/
580
g_object_unref( vi );
584
vips_history_invalidate_cb( Imageinfo *ii, VipsInfo *vi )
587
printf( "vips_history_invalidate_cb: "
588
"on invalidate of ii, uncaching \"%s\"\n", vi->name );
589
#endif /*DEBUG_HISTORY*/
591
g_object_unref( vi );
594
/* Add a function call to the history.
597
vips_history_add( VipsInfo *vi )
601
#ifdef DEBUG_HISTORY_SANITY
602
vips_history_sanity();
603
#endif /*DEBUG_HISTORY_SANITY*/
606
printf( "vips_history_add: adding \"%s\" (%p), hash = %u\n",
607
vi->name, vi, vi->hash );
608
#endif /*DEBUG_HISTORY*/
610
g_assert( !g_hash_table_lookup( vips_history_table, vi ) );
611
g_assert( !vi->in_cache );
613
g_hash_table_insert( vips_history_table, vi, vi );
614
vips_history_size += 1;
616
g_assert( g_hash_table_lookup( vips_history_table, vi ) );
618
queue_add( vips_history_lru, vi );
622
/* If any of our ii are destroyed, we must go too.
624
for( i = 0; i < vi->noutii; i++ )
625
vi->outii_destroy_sid[i] = g_signal_connect( vi->outii[i],
627
G_CALLBACK( vips_history_destroy_cb ), vi );
629
/* If any of our input ii are destroyed or painted on, we must also
632
for( i = 0; i < vi->ninii; i++ ) {
633
vi->inii_destroy_sid[i] = g_signal_connect( vi->inii[i],
635
G_CALLBACK( vips_history_destroy_cb ), vi );
636
vi->inii_invalidate_sid[i] = g_signal_connect( vi->inii[i],
638
G_CALLBACK( vips_history_invalidate_cb ), vi );
641
/* History too big? Flush!
643
if( queue_length( vips_history_lru ) > VIPS_HISTORY_MAX )
644
vips_history_remove_lru();
646
#ifdef DEBUG_HISTORY_SANITY
647
vips_history_sanity();
648
#endif /*DEBUG_HISTORY_SANITY*/
651
/* Sort out the input images.
654
vips_gather( VipsInfo *vi )
664
/* Can we LUT? Function needs to be LUTable, all input images
665
* have to be the same underlying image, and image must be uncoded
668
vi->use_lut = (vi->fn->flags & IM_FN_PTOP) &&
669
imageinfo_same_underlying( vi->inii, vi->ninii ) &&
670
imageinfo_get_underlying( vi->inii[0] )->Coding ==
672
imageinfo_get_underlying( vi->inii[0] )->BandFmt ==
676
for( i = 0; i < vi->noutii; i++ )
677
imageinfo_set_underlying( vi->outii[i], vi->inii[0] );
679
/* Now fill the vargv vector with the IMAGE pointers.
682
for( i = 0; i < vi->fn->argc; i++ ) {
683
im_type_desc *ty = vi->fn->argv[i].desc;
685
if( !vips_type_needs_input( ty ) )
688
if( strcmp( ty->type, IM_TYPE_IMAGE ) == 0 ) {
689
Imageinfo *inii = vi->inii[ni++];
692
if( !(im = imageinfo_get( vi->use_lut, inii )) )
695
/* RW operations need an extra copy. Tyhe vargv will
696
* already have been created by vips_build_output().
698
if( ty->flags & IM_TYPE_RW ) {
699
if( im_copy( im, vi->vargv[i] ) )
706
if( strcmp( ty->type, IM_TYPE_IMAGEVEC ) == 0 ) {
707
im_imagevec_object *iv =
708
(im_imagevec_object *) vi->vargv[i];
710
/* Found an input image vector. Add all the imageinfo
713
for( j = 0; j < iv->n; j++ ) {
714
Imageinfo *inii = vi->inii[ni++];
717
if( !(im = imageinfo_get( vi->use_lut, inii )) )
725
/* We should have used up all the images exactly.
727
g_assert( ni == vi->ninii );
732
/* VIPS types -> a string buffer. Yuk! Should be a method on object type. This
733
* is used to generate vips history, so it has to be in sh format.
736
vips_tochar_shell( VipsInfo *vi, int i, VipsBuf *buf )
738
im_object obj = vi->vargv[i];
739
im_type_desc *ty = vi->fn->argv[i].desc;
741
switch( vips_lookup_type( ty->type ) ) {
743
vips_buf_appendf( buf, "%g", *((double*)obj) );
747
vips_buf_appendf( buf, "%d", *((int*)obj) );
751
vips_buf_appendf( buf, "(%g, %g)",
752
((double*)obj)[0], ((double*)obj)[1] );
756
vips_buf_appendf( buf, "\"%s\"", (char*)obj );
761
IMAGE *im = (IMAGE *) obj;
763
/* In quotes, in case there are spaces in the
764
* filename. We also need to test im, as we might be called
765
* before the im has been generated.
767
vips_buf_appendf( buf, "\"%s\"", im ? im->filename : "null" );
775
im_mask_object *mo = obj;
777
vips_buf_appendf( buf, "%s", NN( mo->name ) );
784
im_doublevec_object *v = (im_doublevec_object *) obj;
787
vips_buf_appendf( buf, "\"" );
788
for( j = 0; j < v->n; j++ )
789
vips_buf_appendf( buf, "%g ", v->vec[j] );
790
vips_buf_appendf( buf, "\"" );
797
im_intvec_object *v = (im_intvec_object *) obj;
800
vips_buf_appendf( buf, "\"" );
801
for( j = 0; j < v->n; j++ )
802
vips_buf_appendf( buf, "%d ", v->vec[j] );
803
vips_buf_appendf( buf, "\"" );
810
im_imagevec_object *v = (im_imagevec_object *) obj;
813
vips_buf_appendf( buf, "\"" );
814
for( j = 0; j < v->n; j++ )
815
vips_buf_appendf( buf, "%s ", v->vec[j]->filename );
816
vips_buf_appendf( buf, "\"" );
823
GValue *value = (GValue *) obj;
825
vips_buf_appendgv( buf, value );
830
case VIPS_INTERPOLATE:
831
vips_object_to_string( VIPS_OBJECT( obj ), buf );
835
if( strcmp( ty->type, IM_TYPE_DISPLAY ) == 0 )
838
vips_buf_appendf( buf, "sRGB" );
846
/* VIPS types -> a buffer. For tracing calls and debug.
849
vips_tochar_trace( VipsInfo *vi, int i, VipsBuf *buf )
851
im_object obj = vi->vargv[i];
852
im_type_desc *vips = vi->fn->argv[i].desc;
854
switch( vips_lookup_type( vips->type ) ) {
856
vips_buf_appendf( buf, "%g", *((double*)obj) );
860
vips_buf_appendf( buf, "%d", *((int*)obj) );
864
vips_buf_appendf( buf, "(%g, %g)",
865
((double*)obj)[0], ((double*)obj)[1] );
869
vips_buf_appendf( buf, "\"%s\"", (char*) obj );
873
vips_buf_appendi( buf, (IMAGE *) obj );
877
vips_buf_appendf( buf, "dmask" );
881
vips_buf_appendf( buf, "imask" );
885
vips_buf_appendf( buf, "doublevec" );
889
vips_buf_appendf( buf, "intvec" );
893
vips_buf_appendf( buf, "imagevec" );
898
GValue *value = (GValue *) obj;
900
vips_buf_appends( buf, "(gvalue" );
901
vips_buf_appendgv( buf, value );
902
vips_buf_appendf( buf, ")" );
907
case VIPS_INTERPOLATE:
908
vips_object_to_string( VIPS_OBJECT( obj ), buf );
916
/* Get the args from the VIPS call buffer.
919
vips_args_vips( VipsInfo *vi, VipsBuf *buf )
923
vips_buf_appendf( buf, _( "You passed:" ) );
924
vips_buf_appendf( buf, "\n" );
925
for( i = 0; i < vi->fn->argc; i++ ) {
926
im_type_desc *ty = vi->fn->argv[i].desc;
927
char *name = vi->fn->argv[i].name;
929
if( vips_type_needs_input( ty ) ) {
930
vips_buf_appendf( buf, " %s - ", name );
931
vips_tochar_trace( vi, i, buf );
932
vips_buf_appendf( buf, "\n" );
937
/* There's a problem calling the function. Show args from the vips call
941
vips_error_fn_vips( VipsInfo *vi )
944
VipsBuf buf = VIPS_BUF_STATIC( txt );
946
error_top( _( "VIPS library error." ) );
948
vips_buf_appendf( &buf,
949
_( "Error calling library function \"%s\" (%s)." ),
950
vi->name, vi->fn->desc );
951
vips_buf_appendf( &buf, "\n" );
952
vips_buf_appendf( &buf, _( "VIPS library: %s" ), im_error_buffer() );
954
vips_buf_appendf( &buf, "\n" );
955
vips_args_vips( vi, &buf );
956
vips_buf_appendf( &buf, "\n" );
957
vips_usage( &buf, vi->fn );
958
error_sub( "%s", vips_buf_all( &buf ) );
962
vips_build_argv( VipsInfo *vi, char **argv )
966
for( i = 0; i < vi->fn->argc; i++ ) {
968
VipsBuf buf = VIPS_BUF_STATIC( txt );
970
vips_tochar_shell( vi, i, &buf );
971
if( !(argv[i] = im_strdup( NULL, vips_buf_all( &buf ) )) )
976
printf( "vips_build_argv: argv for %s is:\n ", vi->fn->name );
977
for( i = 0; i < vi->fn->argc; i++ )
978
printf( "%s ", NN( argv[i] ) );
986
vips_free_argv( int argc, char **argv )
990
for( i = 0; i < argc; i++ ) {
996
/* Update the VIPS hist for all output images.
999
vips_update_hist( VipsInfo *vi )
1001
int argc = vi->fn->argc;
1006
printf( "vips_update_hist: %s\n", vi->name );
1009
/* No output images? Nothing to do.
1011
if( vi->nires == 0 )
1014
/* Build an argv for this call. +1 for NULL termination.
1016
if( !(argv = IM_ARRAY( NULL, argc + 1, char * )) )
1018
for( i = 0; i < argc + 1; i++ )
1020
if( !vips_build_argv( vi, argv ) ) {
1021
vips_free_argv( argc, argv );
1025
for( i = 0; i < vi->nres; i++ ) {
1026
int j = vi->outpos[i];
1027
im_type_desc *ty = vi->fn->argv[j].desc;
1031
if( vips_lookup_type( ty->type ) == VIPS_IMAGE ) {
1033
printf( "vips_update_hist: adding to arg %d\n", j );
1036
im_updatehist( vi->vargv[j], vi->fn->name, argc, argv );
1040
vips_free_argv( argc, argv );
1043
/* Call a vips operation.
1045
* The cache takes ownership of the VipsInfo passed in, and returns a ref to a
1046
* VipsInfo (might be a different one) that contains the result. Should be
1047
* unreffed when you're done with it.
1049
* On error, return NULL.
1052
vips_dispatch( VipsInfo *vi, PElement *out )
1056
#ifdef DEBUG_HISTORY_SANITY
1057
vips_history_sanity();
1058
#endif /*DEBUG_HISTORY_SANITY*/
1060
/* Calculate the hash for this vi after building it, but before we do
1063
* We want the hash to reflect the args as supplied by nip2, not the
1064
* args as transformed by vips_gather() for this specific call.
1066
(void) vips_hash( vi );
1068
/* Look over the images we have and turn input Imageinfos to IMAGEs.
1069
* If we can do this with a lut, set all that up.
1071
if( !vips_gather( vi ) ) {
1072
g_object_unref( vi );
1076
/* We have to show args after gather, since the tracer wants IMAGE not
1083
for( i = 0; i < vi->fn->argc; i++ ) {
1084
im_type_desc *ty = vi->fn->argv[i].desc;
1087
VipsBuf buf = VIPS_BUF_STATIC( txt );
1089
printf( "vips_fill_spine: arg[%d] (%s) = ", i, ty->type );
1090
vips_tochar_trace( vi, i, &buf );
1091
printf( "%s\n", vips_buf_all( &buf ) );
1096
/* Is this function call in the history?
1098
if( (old_vi = vips_history_lookup( vi )) ) {
1099
/* Yes: reuse! unref our arg to junk it, adda ref to the
1100
* cached call for our caller.
1102
g_object_unref( vi );
1106
if( trace_flags & TRACE_VIPS )
1107
vips_buf_appendf( trace_current(), "(from cache) " );
1109
#ifdef DEBUG_HISTORY
1110
printf( "vips_dispatch: found %s in history\n", vi->name );
1111
#endif /*DEBUG_HISTORY*/
1114
/* No: call function.
1119
static GTimer *timer = NULL;
1122
timer = g_timer_new();
1123
g_timer_reset( timer );
1124
#endif /*DEBUG_TIME*/
1126
#ifdef DEBUG_HISTORY_MISS
1127
printf( "vips_dispatch: calling %s\n", vi->name );
1128
#endif /*DEBUG_HISTORY_MISS*/
1130
/* Be careful. Eval callbacks from this may do anything,
1131
* including call vips_dispatch().
1133
result = vi->fn->disp( vi->vargv );
1136
printf( "vips_dispatch: %s - %g seconds\n",
1137
vi->name, g_timer_elapsed( timer, NULL ) );
1138
#endif /*DEBUG_TIME*/
1141
vips_error_fn_vips( vi );
1142
g_object_unref( vi );
1145
vips_update_hist( vi );
1148
/* Add to our operation cache, if necessary.
1150
if( !(vi->fn->flags & IM_FN_NOCACHE) ) {
1152
/* Already in the history. Just touch the time.
1154
vips_history_touch( vi );
1155
else if( (old_vi = vips_history_lookup( vi )) ) {
1156
/* We have an equal but older item there? This can
1157
* happen with nested calls. Touch the old one.
1159
vips_history_touch( old_vi );
1163
vips_history_add( vi );
1166
#ifdef DEBUG_HISTORY_SANITY
1167
vips_history_sanity();
1168
#endif /*DEBUG_HISTORY_SANITY*/