~ubuntu-branches/ubuntu/vivid/nip2/vivid-proposed

« back to all changes in this revision

Viewing changes to src/vips_cache.c

  • Committer: Bazaar Package Importer
  • Author(s): Jay Berkenbilt
  • Date: 2010-12-27 14:53:08 UTC
  • mfrom: (2.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20101227145308-vampjbuuft281j3l
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Call vips functions, cache recent results
 
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
 
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
 
21
 
 
22
 */
 
23
 
 
24
/*
 
25
 
 
26
    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
 
27
 
 
28
 */
 
29
 
 
30
#include "ip.h"
 
31
 
 
32
/*
 
33
#define DEBUG_TIME
 
34
#define DEBUG_HISTORY_SANITY
 
35
#define DEBUG_HISTORY_MISS
 
36
#define DEBUG
 
37
#define DEBUG_HISTORY
 
38
 */
 
39
 
 
40
/* This is usually turned on from a -D in cflags.
 
41
#define DEBUG_LEAK
 
42
 */
 
43
 
 
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
 
46
 * get GCed.
 
47
#undef DEBUG_LEAK
 
48
 */
 
49
 
 
50
/* The previous function calls we are caching, plus an LRU queue for flushing.
 
51
 */
 
52
static GHashTable *vips_history_table = NULL;
 
53
static Queue *vips_history_lru = NULL;
 
54
int vips_history_size = 0;
 
55
 
 
56
/* Hash from a vargv ... just look at input args and the function name.
 
57
 */
 
58
static unsigned int
 
59
vips_hash( VipsInfo *vi )
 
60
{
 
61
        int i;
 
62
        unsigned int hash;
 
63
 
 
64
        if( vi->found_hash )
 
65
                return( vi->hash );
 
66
 
 
67
        hash = 0;
 
68
 
 
69
/* add ints, floats, pointers and strings to the hash.
 
70
 
 
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?
 
73
 
 
74
 */
 
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 );
 
79
 
 
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.
 
82
         */
 
83
        HASH_P( vi->fn );
 
84
 
 
85
        for( i = 0; i < vi->fn->argc; i++ ) {
 
86
                im_type_desc *ty = vi->fn->argv[i].desc;
 
87
 
 
88
                if( vips_type_needs_input( ty ) ) {
 
89
                        switch( vips_lookup_type( ty->type ) ) {
 
90
                        case VIPS_DOUBLE:
 
91
                                HASH_D( *((double *) vi->vargv[i]) );
 
92
                                break;
 
93
 
 
94
                        case VIPS_INT:
 
95
                                HASH_I( *((int *) vi->vargv[i]) );
 
96
                                break;
 
97
 
 
98
                        case VIPS_COMPLEX:
 
99
                                HASH_D( ((double *) vi->vargv[i])[0] );
 
100
                                HASH_D( ((double *) vi->vargv[i])[1] );
 
101
                                break;
 
102
 
 
103
                        case VIPS_STRING:
 
104
                                HASH_S( (char *) vi->vargv[i] );
 
105
                                break;
 
106
 
 
107
                        case VIPS_GVALUE:
 
108
                        case VIPS_INTERPOLATE:
 
109
                                break;
 
110
 
 
111
                        case VIPS_DOUBLEVEC:
 
112
                        {
 
113
                                im_doublevec_object *v = 
 
114
                                        (im_doublevec_object *) vi->vargv[i];
 
115
                                int j;
 
116
 
 
117
                                for( j = 0; j < v->n; j++ )
 
118
                                        HASH_D( v->vec[j] );
 
119
 
 
120
                                break;
 
121
                        }
 
122
 
 
123
                        case VIPS_INTVEC:
 
124
                        {
 
125
                                im_intvec_object *v = 
 
126
                                        (im_intvec_object *) vi->vargv[i];
 
127
                                int j;
 
128
 
 
129
                                for( j = 0; j < v->n; j++ )
 
130
                                        HASH_I( v->vec[j] );
 
131
 
 
132
                                break;
 
133
                        }
 
134
 
 
135
                        case VIPS_DMASK:
 
136
                        {
 
137
                                im_mask_object *mo = vi->vargv[i];
 
138
                                DOUBLEMASK *mask = mo->mask;
 
139
 
 
140
                                /* mask can be NULL if we are called after 
 
141
                                 * vips_new() but before we've built the arg
 
142
                                 * list.
 
143
                                 */
 
144
                                if( mask ) {
 
145
                                        int ne = mask->xsize * mask->ysize;
 
146
                                        int j;
 
147
 
 
148
                                        for( j = 0; j < ne; j++ )
 
149
                                                HASH_D( mask->coeff[j] );
 
150
                                        HASH_D( mask->scale );
 
151
                                        HASH_D( mask->offset );
 
152
                                }
 
153
 
 
154
                                break;
 
155
                        }
 
156
 
 
157
                        case VIPS_IMASK:
 
158
                        {
 
159
                                im_mask_object *mo = vi->vargv[i];
 
160
                                INTMASK *mask = mo->mask;
 
161
 
 
162
                                /* mask can be NULL if we are called after 
 
163
                                 * vips_new() but before we've built the arg
 
164
                                 * list.
 
165
                                 */
 
166
                                if( mask ) {
 
167
                                        int ne = mask->xsize * mask->ysize;
 
168
                                        int j;
 
169
 
 
170
                                        for( j = 0; j < ne; j++ )
 
171
                                                HASH_I( mask->coeff[j] );
 
172
                                        HASH_I( mask->scale );
 
173
                                        HASH_I( mask->offset );
 
174
                                }
 
175
 
 
176
                                break;
 
177
                        }
 
178
 
 
179
                        default:
 
180
                        case VIPS_NONE:
 
181
                                break;
 
182
                        }
 
183
                }
 
184
        }
 
185
 
 
186
        /* And the input images.
 
187
         */
 
188
        for( i = 0; i < vi->ninii; i++ )
 
189
                HASH_P( vi->inii[i] );
 
190
 
 
191
        vi->found_hash = TRUE;
 
192
        vi->hash = hash;
 
193
 
 
194
        return( hash );
 
195
}
 
196
 
 
197
/* Are two function calls equal. Check the func and the input args.
 
198
 */
 
199
static gboolean
 
200
vips_equal( VipsInfo *vi1, VipsInfo *vi2 ) 
 
201
{
 
202
        int i;
 
203
        im_function *fn = vi1->fn;
 
204
 
 
205
        if( vi1 == vi2 )
 
206
                return( TRUE );
 
207
 
 
208
        if( vi1->fn != vi2->fn )
 
209
                return( FALSE );
 
210
 
 
211
        for( i = 0; i < fn->argc; i++ ) {
 
212
                im_type_desc *ty = fn->argv[i].desc;
 
213
 
 
214
                if( vips_type_needs_input( ty ) ) {
 
215
                        switch( vips_lookup_type( ty->type ) ) {
 
216
                        case VIPS_DOUBLE:
 
217
                                if( *((double *) vi1->vargv[i]) != 
 
218
                                        *((double *) vi2->vargv[i]) )
 
219
                                        return( FALSE );
 
220
                                break;
 
221
 
 
222
                        case VIPS_INT:
 
223
                                if( *((int *) vi1->vargv[i]) != 
 
224
                                        *((int *) vi2->vargv[i]) )
 
225
                                        return( FALSE );
 
226
                                break;
 
227
 
 
228
                        case VIPS_COMPLEX:
 
229
                                if( ((double *) vi1->vargv[i])[0] != 
 
230
                                        ((double *) vi2->vargv[i])[0] )
 
231
                                        return( FALSE );
 
232
                                if( ((double *) vi1->vargv[i])[1] != 
 
233
                                        ((double *) vi2->vargv[i])[1] )
 
234
                                        return( FALSE );
 
235
                                break;
 
236
 
 
237
                        case VIPS_STRING:
 
238
                                if( strcmp( (char *) vi1->vargv[i],
 
239
                                        (char *) vi2->vargv[i] ) != 0 )
 
240
                                        return( FALSE );
 
241
                                break;
 
242
 
 
243
                        case VIPS_DOUBLEVEC:
 
244
                        {
 
245
                                im_doublevec_object *v1 = 
 
246
                                        (im_doublevec_object *) vi1->vargv[i];
 
247
                                im_doublevec_object *v2 = 
 
248
                                        (im_doublevec_object *) vi2->vargv[i];
 
249
                                int j;
 
250
 
 
251
                                for( j = 0; j < v1->n; j++ )
 
252
                                        if( v1->vec[j] != v2->vec[j] )
 
253
                                                return( FALSE );
 
254
 
 
255
                                break;
 
256
                        }
 
257
 
 
258
                        case VIPS_INTVEC:
 
259
                        {
 
260
                                im_intvec_object *v1 = 
 
261
                                        (im_intvec_object *) vi1->vargv[i];
 
262
                                im_intvec_object *v2 = 
 
263
                                        (im_intvec_object *) vi2->vargv[i];
 
264
                                int j;
 
265
 
 
266
                                for( j = 0; j < v1->n; j++ )
 
267
                                        if( v1->vec[j] != v2->vec[j] )
 
268
                                                return( FALSE );
 
269
 
 
270
                                break;
 
271
                        }
 
272
 
 
273
                        case VIPS_DMASK:
 
274
                        {
 
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;
 
282
                                int j;
 
283
        
 
284
                                if( mask1->xsize != mask2->xsize ||
 
285
                                        mask1->ysize != mask2->ysize )
 
286
                                        return( FALSE );
 
287
 
 
288
                                for( j = 0; j < ne; j++ )
 
289
                                        if( mask1->coeff[j] != mask2->coeff[j] )
 
290
                                                return( FALSE );
 
291
 
 
292
                                if( mask1->scale != mask2->scale )
 
293
                                        return( FALSE );
 
294
                                if( mask1->offset != mask2->offset ) 
 
295
                                        return( FALSE );
 
296
 
 
297
                                break;
 
298
                        }
 
299
 
 
300
                        case VIPS_IMASK:
 
301
                        {
 
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;
 
309
                                int j;
 
310
        
 
311
                                if( mask1->xsize != mask2->xsize ||
 
312
                                        mask1->ysize != mask2->ysize )
 
313
                                        return( FALSE );
 
314
 
 
315
                                for( j = 0; j < ne; j++ )
 
316
                                        if( mask1->coeff[j] != mask2->coeff[j] )
 
317
                                                return( FALSE );
 
318
 
 
319
                                if( mask1->scale != mask2->scale )
 
320
                                        return( FALSE );
 
321
                                if( mask1->offset != mask2->offset ) 
 
322
                                        return( FALSE );
 
323
 
 
324
                                break;
 
325
                        }
 
326
 
 
327
                        case VIPS_IMAGEVEC:
 
328
                        {
 
329
                                im_imagevec_object *v1 = 
 
330
                                        (im_imagevec_object *) vi1->vargv[i];
 
331
                                im_imagevec_object *v2 = 
 
332
                                        (im_imagevec_object *) vi2->vargv[i];
 
333
 
 
334
                                if( v1->n != v2->n )
 
335
                                        return( FALSE );
 
336
 
 
337
                                break;
 
338
                        }
 
339
 
 
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.
 
343
                         */
 
344
                        case VIPS_GVALUE:
 
345
                                if( vi1->vargv[i] != vi2->vargv[i] )
 
346
                                        return( FALSE );
 
347
                                break;
 
348
 
 
349
                        case VIPS_INTERPOLATE:
 
350
                                if( vi1->vargv[i] != vi2->vargv[i] )
 
351
                                        return( FALSE );
 
352
                                break;
 
353
 
 
354
                        default:
 
355
                        case VIPS_NONE:
 
356
                                break;
 
357
                        }
 
358
                }
 
359
        }
 
360
 
 
361
        /* And the input images.
 
362
         */
 
363
        if( vi1->ninii != vi2->ninii )
 
364
                return( FALSE );
 
365
        for( i = 0; i < vi1->ninii; i++ )
 
366
                if( vi1->inii[i] != vi2->inii[i] )
 
367
                        return( FALSE );
 
368
 
 
369
        return( TRUE );
 
370
}
 
371
 
 
372
#ifdef DEBUG_HISTORY_SANITY
 
373
static void
 
374
vips_history_sanity_sub( VipsInfo *vi )
 
375
{
 
376
        g_assert( g_slist_find( vips_history_lru->list, vi ) );
 
377
}
 
378
 
 
379
static void
 
380
vips_history_sanity( void )
 
381
{
 
382
        GSList *p;
 
383
 
 
384
        if( !vips_history_lru || !vips_history_table )
 
385
                return;
 
386
 
 
387
        /* Everything that's on the LRU should be in the history table.
 
388
         */
 
389
        for( p = vips_history_lru->list; p; p = p->next ) {
 
390
                VipsInfo *vi = (VipsInfo *) p->data;
 
391
 
 
392
                g_assert( g_hash_table_lookup( vips_history_table, vi ) );
 
393
 
 
394
                g_assert( vi->fn );
 
395
                g_assert( vi->fn->argc > 0 && vi->fn->argc < MAX_VIPS_ARGS );
 
396
                g_assert( vi->in_cache );
 
397
        }
 
398
 
 
399
        /* Everything that's on the history table should be in the LRU.
 
400
         */
 
401
        g_hash_table_foreach( vips_history_table,
 
402
                (GHFunc) vips_history_sanity_sub, NULL );
 
403
 
 
404
        /* Everything that's on the LRU should be in the global vips_info
 
405
         * list.
 
406
         */
 
407
        for( p = vips_history_lru->list; p; p = p->next ) {
 
408
                VipsInfo *vi = (VipsInfo *) p->data;
 
409
 
 
410
                /* Need to build with DEBUG on before vips_info_all is
 
411
                 * maintained.
 
412
                 */
 
413
                g_assert( g_slist_find( vips_info_all, vi ) );
 
414
        }
 
415
 
 
416
        /* Everything on vips_info_all that's not in vips_history_table should
 
417
         * have in_cache FALSE.
 
418
         */
 
419
        for( p = vips_info_all; p; p = p->next ) {
 
420
                VipsInfo *vi = (VipsInfo *) p->data;
 
421
 
 
422
                if( !g_hash_table_lookup( vips_history_table, vi ) )
 
423
                        g_assert( !vi->in_cache );
 
424
        }
 
425
 
 
426
        /* Every input image argument on every in-cache call should be sane.
 
427
         */
 
428
        for( p = vips_info_all; p; p = p->next ) {
 
429
                VipsInfo *vi = (VipsInfo *) p->data;
 
430
                int i;
 
431
 
 
432
                if( !vi->in_cache )
 
433
                        continue;
 
434
 
 
435
                for( i = 0; i < vi->fn->argc; i++ ) {
 
436
                        im_type_desc *ty = vi->fn->argv[i].desc;
 
437
 
 
438
                        if( !vips_type_needs_input( ty ) )
 
439
                                continue;
 
440
 
 
441
                        if( strcmp( ty->type, IM_TYPE_IMAGE ) == 0 ) {
 
442
                                IMAGE *im = (IMAGE *) vi->vargv[i];
 
443
 
 
444
                                g_assert( !im_image_sanity( im ) );
 
445
                        }
 
446
                        else if( strcmp( ty->type, IM_TYPE_IMAGEVEC ) == 0 ) {
 
447
                                im_imagevec_object *iv = 
 
448
                                        (im_imagevec_object *) vi->vargv[i];
 
449
                                int j;
 
450
 
 
451
                                for( j = 0; j < iv->n; j++) 
 
452
                                        g_assert( !im_image_sanity( 
 
453
                                                iv->vec[j] ) );
 
454
                        }
 
455
                }
 
456
        }
 
457
 
 
458
        /* All the output images should be sane.
 
459
         */
 
460
        for( p = vips_info_all; p; p = p->next ) {
 
461
                VipsInfo *vi = (VipsInfo *) p->data;
 
462
                int i;
 
463
 
 
464
                if( !vi->in_cache )
 
465
                        continue;
 
466
 
 
467
                for( i = 0; i < vi->noutii; i++ ) {
 
468
                        IMAGE *im;
 
469
 
 
470
                        if( (im = imageinfo_get( FALSE, vi->outii[i] )) )
 
471
                                g_assert( !im_image_sanity( im ) );
 
472
                }
 
473
        }
 
474
}
 
475
#endif /*DEBUG_HISTORY_SANITY */
 
476
 
 
477
/* Is a function call in our history? Return the old one. 
 
478
 */
 
479
static VipsInfo *
 
480
vips_history_lookup( VipsInfo *vi )
 
481
{
 
482
        VipsInfo *old_vi;
 
483
 
 
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();
 
488
        }
 
489
 
 
490
        old_vi = (VipsInfo *) g_hash_table_lookup( vips_history_table, vi );
 
491
 
 
492
#ifdef DEBUG_HISTORY
 
493
        if( old_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*/
 
499
 
 
500
        return( old_vi );
 
501
}
 
502
 
 
503
/* Bump to end of LRU.
 
504
 */
 
505
static void
 
506
vips_history_touch( VipsInfo *vi )
 
507
{
 
508
        g_assert( vi->in_cache );
 
509
 
 
510
        queue_remove( vips_history_lru, vi );
 
511
        queue_add( vips_history_lru, vi );
 
512
 
 
513
#ifdef DEBUG_HISTORY_SANITY
 
514
        vips_history_sanity();
 
515
#endif /*DEBUG_HISTORY_SANITY*/
 
516
#ifdef DEBUG_HISTORY
 
517
        printf( "vips_history_touch: bumping \"%s\"\n", vi->name );
 
518
#endif /*DEBUG_HISTORY*/
 
519
}
 
520
 
 
521
/* Are we in the history? Remove us. Called from vips_info_dispose() on unref, 
 
522
 * don't call this directly.
 
523
 */
 
524
void
 
525
vips_history_remove( VipsInfo *vi )
 
526
{
 
527
        int i;
 
528
 
 
529
        if( vi->in_cache ) {
 
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;
 
534
 
 
535
#ifdef DEBUG_HISTORY
 
536
                printf( "vips_history_remove: removing \"%s\"\n", vi->name );
 
537
#endif /*DEBUG_HISTORY*/
 
538
        }
 
539
 
 
540
        /* Disconnect signals.
 
541
         */
 
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] ); 
 
547
        }
 
548
 
 
549
#ifdef DEBUG_HISTORY_SANITY
 
550
        vips_history_sanity();
 
551
#endif /*DEBUG_HISTORY_SANITY*/
 
552
}
 
553
 
 
554
static void
 
555
vips_history_remove_lru( void )
 
556
{
 
557
        VipsInfo *vi;
 
558
 
 
559
        vi = (VipsInfo *) queue_head( vips_history_lru );
 
560
 
 
561
#ifdef DEBUG_HISTORY
 
562
        printf( "vips_history_remove_lru: flushing \"%s\"\n", vi->name );
 
563
#endif /*DEBUG_HISTORY*/
 
564
 
 
565
        g_object_unref( vi );
 
566
 
 
567
#ifdef DEBUG_HISTORY_SANITY
 
568
        vips_history_sanity();
 
569
#endif /*DEBUG_HISTORY_SANITY*/
 
570
}
 
571
 
 
572
static void
 
573
vips_history_destroy_cb( Imageinfo *ii, VipsInfo *vi )
 
574
{
 
575
#ifdef DEBUG_HISTORY
 
576
        printf( "vips_history_destroy_cb: on death of ii, uncaching \"%s\"\n", 
 
577
                vi->name );
 
578
#endif /*DEBUG_HISTORY*/
 
579
 
 
580
        g_object_unref( vi );
 
581
}
 
582
 
 
583
static void
 
584
vips_history_invalidate_cb( Imageinfo *ii, VipsInfo *vi )
 
585
{
 
586
#ifdef DEBUG_HISTORY
 
587
        printf( "vips_history_invalidate_cb: "
 
588
                "on invalidate of ii, uncaching \"%s\"\n", vi->name );
 
589
#endif /*DEBUG_HISTORY*/
 
590
 
 
591
        g_object_unref( vi );
 
592
}
 
593
 
 
594
/* Add a function call to the history. 
 
595
 */
 
596
static void
 
597
vips_history_add( VipsInfo *vi )
 
598
{
 
599
        int i;
 
600
 
 
601
#ifdef DEBUG_HISTORY_SANITY
 
602
        vips_history_sanity();
 
603
#endif /*DEBUG_HISTORY_SANITY*/
 
604
 
 
605
#ifdef DEBUG_HISTORY
 
606
        printf( "vips_history_add: adding \"%s\" (%p), hash = %u\n", 
 
607
                vi->name, vi, vi->hash );
 
608
#endif /*DEBUG_HISTORY*/
 
609
 
 
610
        g_assert( !g_hash_table_lookup( vips_history_table, vi ) );
 
611
        g_assert( !vi->in_cache );
 
612
 
 
613
        g_hash_table_insert( vips_history_table, vi, vi );
 
614
        vips_history_size += 1;
 
615
 
 
616
        g_assert( g_hash_table_lookup( vips_history_table, vi ) );
 
617
 
 
618
        queue_add( vips_history_lru, vi );
 
619
        vi->in_cache = TRUE;
 
620
        g_object_ref( vi );
 
621
 
 
622
        /* If any of our ii are destroyed, we must go too.
 
623
         */
 
624
        for( i = 0; i < vi->noutii; i++ )
 
625
                vi->outii_destroy_sid[i] = g_signal_connect( vi->outii[i], 
 
626
                        "destroy", 
 
627
                        G_CALLBACK( vips_history_destroy_cb ), vi );
 
628
 
 
629
        /* If any of our input ii are destroyed or painted on, we must also 
 
630
         * uncache.
 
631
         */
 
632
        for( i = 0; i < vi->ninii; i++ ) {
 
633
                vi->inii_destroy_sid[i] = g_signal_connect( vi->inii[i], 
 
634
                        "destroy", 
 
635
                        G_CALLBACK( vips_history_destroy_cb ), vi );
 
636
                vi->inii_invalidate_sid[i] = g_signal_connect( vi->inii[i], 
 
637
                        "invalidate", 
 
638
                        G_CALLBACK( vips_history_invalidate_cb ), vi );
 
639
        }
 
640
 
 
641
        /* History too big? Flush!
 
642
         */
 
643
        if( queue_length( vips_history_lru ) > VIPS_HISTORY_MAX ) 
 
644
                vips_history_remove_lru();
 
645
 
 
646
#ifdef DEBUG_HISTORY_SANITY
 
647
        vips_history_sanity();
 
648
#endif /*DEBUG_HISTORY_SANITY*/
 
649
}
 
650
 
 
651
/* Sort out the input images. 
 
652
 */
 
653
static gboolean
 
654
vips_gather( VipsInfo *vi ) 
 
655
{
 
656
        int i, j;
 
657
        int ni;
 
658
 
 
659
        /* No input images.
 
660
         */
 
661
        if( vi->ninii == 0 )
 
662
                return( TRUE );
 
663
 
 
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
 
666
         * IM_BANDFMT_UCHAR.
 
667
         */
 
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 == 
 
671
                        IM_CODING_NONE &&
 
672
                imageinfo_get_underlying( vi->inii[0] )->BandFmt == 
 
673
                        IM_BANDFMT_UCHAR;
 
674
 
 
675
        if( vi->use_lut ) 
 
676
                for( i = 0; i < vi->noutii; i++ )
 
677
                        imageinfo_set_underlying( vi->outii[i], vi->inii[0] );
 
678
 
 
679
        /* Now fill the vargv vector with the IMAGE pointers.
 
680
         */
 
681
        ni = 0;
 
682
        for( i = 0; i < vi->fn->argc; i++ ) {
 
683
                im_type_desc *ty = vi->fn->argv[i].desc;
 
684
 
 
685
                if( !vips_type_needs_input( ty ) ) 
 
686
                        continue;
 
687
 
 
688
                if( strcmp( ty->type, IM_TYPE_IMAGE ) == 0 ) { 
 
689
                        Imageinfo *inii = vi->inii[ni++];
 
690
                        IMAGE *im;
 
691
 
 
692
                        if( !(im = imageinfo_get( vi->use_lut, inii )) )
 
693
                                return( FALSE );
 
694
 
 
695
                        /* RW operations need an extra copy. Tyhe vargv will
 
696
                         * already have been created by vips_build_output().
 
697
                         */
 
698
                        if( ty->flags & IM_TYPE_RW ) {
 
699
                                if( im_copy( im, vi->vargv[i] ) )
 
700
                                        return( FALSE );
 
701
                        }
 
702
                        else
 
703
                                vi->vargv[i] = im; 
 
704
                }
 
705
 
 
706
                if( strcmp( ty->type, IM_TYPE_IMAGEVEC ) == 0 ) {
 
707
                        im_imagevec_object *iv = 
 
708
                                (im_imagevec_object *) vi->vargv[i];
 
709
 
 
710
                        /* Found an input image vector. Add all the imageinfo
 
711
                         * in the vector.
 
712
                         */
 
713
                        for( j = 0; j < iv->n; j++ ) {
 
714
                                Imageinfo *inii = vi->inii[ni++];
 
715
                                IMAGE *im;
 
716
 
 
717
                                if( !(im = imageinfo_get( vi->use_lut, inii )) )
 
718
                                        return( FALSE );
 
719
 
 
720
                                iv->vec[j] = im;
 
721
                        }
 
722
                }
 
723
        }
 
724
 
 
725
        /* We should have used up all the images exactly.
 
726
         */
 
727
        g_assert( ni == vi->ninii );
 
728
 
 
729
        return( TRUE );
 
730
}
 
731
 
 
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.
 
734
 */
 
735
void
 
736
vips_tochar_shell( VipsInfo *vi, int i, VipsBuf *buf )
 
737
{
 
738
        im_object obj = vi->vargv[i];
 
739
        im_type_desc *ty = vi->fn->argv[i].desc;
 
740
 
 
741
        switch( vips_lookup_type( ty->type ) ) {
 
742
        case VIPS_DOUBLE:
 
743
                vips_buf_appendf( buf, "%g", *((double*)obj) );
 
744
                break;
 
745
 
 
746
        case VIPS_INT:
 
747
                vips_buf_appendf( buf, "%d", *((int*)obj) );
 
748
                break;
 
749
 
 
750
        case VIPS_COMPLEX:
 
751
                vips_buf_appendf( buf, "(%g, %g)", 
 
752
                        ((double*)obj)[0], ((double*)obj)[1] );
 
753
                break;
 
754
 
 
755
        case VIPS_STRING:
 
756
                vips_buf_appendf( buf, "\"%s\"", (char*)obj );
 
757
                break;
 
758
 
 
759
        case VIPS_IMAGE:
 
760
{
 
761
                IMAGE *im = (IMAGE *) obj;
 
762
 
 
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.
 
766
                 */
 
767
                vips_buf_appendf( buf, "\"%s\"", im ? im->filename : "null" );
 
768
 
 
769
                break;
 
770
}
 
771
 
 
772
        case VIPS_DMASK:
 
773
        case VIPS_IMASK:
 
774
        {
 
775
                im_mask_object *mo = obj;
 
776
 
 
777
                vips_buf_appendf( buf, "%s", NN( mo->name ) );
 
778
 
 
779
                break;
 
780
        }
 
781
 
 
782
        case VIPS_DOUBLEVEC:
 
783
        {
 
784
                im_doublevec_object *v = (im_doublevec_object *) obj;
 
785
                int j;
 
786
 
 
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, "\"" );
 
791
 
 
792
                break;
 
793
        }
 
794
 
 
795
        case VIPS_INTVEC:
 
796
        {
 
797
                im_intvec_object *v = (im_intvec_object *) obj;
 
798
                int j;
 
799
 
 
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, "\"" );
 
804
 
 
805
                break;
 
806
        }
 
807
 
 
808
        case VIPS_IMAGEVEC:
 
809
        {
 
810
                im_imagevec_object *v = (im_imagevec_object *) obj;
 
811
                int j;
 
812
 
 
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, "\"" );
 
817
 
 
818
                break;
 
819
        }
 
820
 
 
821
        case VIPS_GVALUE:
 
822
        {
 
823
                GValue *value = (GValue *) obj;
 
824
 
 
825
                vips_buf_appendgv( buf, value );
 
826
 
 
827
                break;
 
828
        }
 
829
 
 
830
        case VIPS_INTERPOLATE:
 
831
                vips_object_to_string( VIPS_OBJECT( obj ), buf );
 
832
                break;
 
833
 
 
834
        case VIPS_NONE:
 
835
                if( strcmp( ty->type, IM_TYPE_DISPLAY ) == 0 ) 
 
836
                        /* Just assume sRGB.
 
837
                         */
 
838
                        vips_buf_appendf( buf, "sRGB" );
 
839
                break;
 
840
 
 
841
        default:
 
842
                g_assert( FALSE );
 
843
        }
 
844
}
 
845
 
 
846
/* VIPS types -> a buffer. For tracing calls and debug.
 
847
 */
 
848
void
 
849
vips_tochar_trace( VipsInfo *vi, int i, VipsBuf *buf )
 
850
{
 
851
        im_object obj = vi->vargv[i];
 
852
        im_type_desc *vips = vi->fn->argv[i].desc;
 
853
 
 
854
        switch( vips_lookup_type( vips->type ) ) {
 
855
        case VIPS_DOUBLE:
 
856
                vips_buf_appendf( buf, "%g", *((double*)obj) );
 
857
                break;
 
858
 
 
859
        case VIPS_INT:
 
860
                vips_buf_appendf( buf, "%d", *((int*)obj) );
 
861
                break;
 
862
 
 
863
        case VIPS_COMPLEX:
 
864
                vips_buf_appendf( buf, "(%g, %g)", 
 
865
                        ((double*)obj)[0], ((double*)obj)[1] );
 
866
                break;
 
867
 
 
868
        case VIPS_STRING:
 
869
                vips_buf_appendf( buf, "\"%s\"", (char*) obj );
 
870
                break;
 
871
 
 
872
        case VIPS_IMAGE:
 
873
                vips_buf_appendi( buf, (IMAGE *) obj );
 
874
                break;
 
875
 
 
876
        case VIPS_DMASK:
 
877
                vips_buf_appendf( buf, "dmask" );
 
878
                break;
 
879
 
 
880
        case VIPS_IMASK:
 
881
                vips_buf_appendf( buf, "imask" );
 
882
                break;
 
883
 
 
884
        case VIPS_DOUBLEVEC:
 
885
                vips_buf_appendf( buf, "doublevec" );
 
886
                break;
 
887
 
 
888
        case VIPS_INTVEC:
 
889
                vips_buf_appendf( buf, "intvec" );
 
890
                break;
 
891
 
 
892
        case VIPS_IMAGEVEC:
 
893
                vips_buf_appendf( buf, "imagevec" );
 
894
                break;
 
895
 
 
896
        case VIPS_GVALUE:
 
897
        {
 
898
                GValue *value = (GValue *) obj;
 
899
 
 
900
                vips_buf_appends( buf, "(gvalue" );
 
901
                vips_buf_appendgv( buf, value );
 
902
                vips_buf_appendf( buf, ")" );
 
903
 
 
904
                break;
 
905
        }
 
906
 
 
907
        case VIPS_INTERPOLATE:
 
908
                vips_object_to_string( VIPS_OBJECT( obj ), buf );
 
909
                break;
 
910
 
 
911
        default:
 
912
                g_assert( FALSE );
 
913
        }
 
914
}
 
915
 
 
916
/* Get the args from the VIPS call buffer.
 
917
 */
 
918
static void
 
919
vips_args_vips( VipsInfo *vi, VipsBuf *buf )
 
920
{
 
921
        int i;
 
922
 
 
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;
 
928
 
 
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" );
 
933
                }
 
934
        }
 
935
}
 
936
 
 
937
/* There's a problem calling the function. Show args from the vips call
 
938
 * struct.
 
939
 */
 
940
static void
 
941
vips_error_fn_vips( VipsInfo *vi )
 
942
{
 
943
        char txt[1000];
 
944
        VipsBuf buf = VIPS_BUF_STATIC( txt );
 
945
 
 
946
        error_top( _( "VIPS library error." ) );
 
947
 
 
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() );
 
953
        im_error_clear();
 
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 ) );
 
959
}
 
960
 
 
961
static gboolean
 
962
vips_build_argv( VipsInfo *vi, char **argv )
 
963
{
 
964
        int i;
 
965
 
 
966
        for( i = 0; i < vi->fn->argc; i++ ) {
 
967
                char txt[512];
 
968
                VipsBuf buf = VIPS_BUF_STATIC( txt );
 
969
 
 
970
                vips_tochar_shell( vi, i, &buf );
 
971
                if( !(argv[i] = im_strdup( NULL, vips_buf_all( &buf ) )) )
 
972
                        return( FALSE );
 
973
        }
 
974
 
 
975
#ifdef DEBUG
 
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] ) );
 
979
        printf( "\n" );
 
980
#endif /*DEBUG*/
 
981
 
 
982
        return( TRUE );
 
983
}
 
984
 
 
985
static void
 
986
vips_free_argv( int argc, char **argv )
 
987
{
 
988
        int i;
 
989
 
 
990
        for( i = 0; i < argc; i++ ) {
 
991
                IM_FREE( argv[i] );
 
992
        }
 
993
        IM_FREE( argv );
 
994
}
 
995
 
 
996
/* Update the VIPS hist for all output images.
 
997
 */
 
998
static void
 
999
vips_update_hist( VipsInfo *vi )
 
1000
{
 
1001
        int argc = vi->fn->argc;
 
1002
        char **argv;
 
1003
        int i;
 
1004
 
 
1005
#ifdef DEBUG
 
1006
        printf( "vips_update_hist: %s\n", vi->name );
 
1007
#endif /*DEBUG*/
 
1008
 
 
1009
        /* No output images? Nothing to do.
 
1010
         */
 
1011
        if( vi->nires == 0 )
 
1012
                return;
 
1013
 
 
1014
        /* Build an argv for this call. +1 for NULL termination.
 
1015
         */
 
1016
        if( !(argv = IM_ARRAY( NULL, argc + 1, char * )) )
 
1017
                return;
 
1018
        for( i = 0; i < argc + 1; i++ )
 
1019
                argv[i] = NULL;
 
1020
        if( !vips_build_argv( vi, argv ) ) {
 
1021
                vips_free_argv( argc, argv );
 
1022
                return;
 
1023
        }
 
1024
 
 
1025
        for( i = 0; i < vi->nres; i++ ) {
 
1026
                int j = vi->outpos[i];
 
1027
                im_type_desc *ty = vi->fn->argv[j].desc;
 
1028
 
 
1029
                /* Image output.
 
1030
                 */
 
1031
                if( vips_lookup_type( ty->type ) == VIPS_IMAGE ) {
 
1032
#ifdef DEBUG
 
1033
                        printf( "vips_update_hist: adding to arg %d\n", j );
 
1034
#endif /*DEBUG*/
 
1035
 
 
1036
                        im_updatehist( vi->vargv[j], vi->fn->name, argc, argv );
 
1037
                }
 
1038
        }
 
1039
 
 
1040
        vips_free_argv( argc, argv );
 
1041
}
 
1042
 
 
1043
/* Call a vips operation. 
 
1044
 *
 
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.
 
1048
 *
 
1049
 * On error, return NULL.
 
1050
 */
 
1051
VipsInfo *
 
1052
vips_dispatch( VipsInfo *vi, PElement *out )
 
1053
{
 
1054
        VipsInfo *old_vi;
 
1055
 
 
1056
#ifdef DEBUG_HISTORY_SANITY
 
1057
        vips_history_sanity();
 
1058
#endif /*DEBUG_HISTORY_SANITY*/
 
1059
 
 
1060
        /* Calculate the hash for this vi after building it, but before we do
 
1061
         * vips_gather();
 
1062
         *
 
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.
 
1065
         */
 
1066
        (void) vips_hash( vi );
 
1067
 
 
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.
 
1070
         */
 
1071
        if( !vips_gather( vi ) ) {
 
1072
                g_object_unref( vi );
 
1073
                return( NULL );
 
1074
        }
 
1075
 
 
1076
        /* We have to show args after gather, since the tracer wants IMAGE not
 
1077
         * Imageinfo.
 
1078
         */
 
1079
#ifdef DEBUG
 
1080
{
 
1081
        int i;
 
1082
 
 
1083
        for( i = 0; i < vi->fn->argc; i++ ) {
 
1084
                im_type_desc *ty = vi->fn->argv[i].desc;
 
1085
 
 
1086
                char txt[512];
 
1087
                VipsBuf buf = VIPS_BUF_STATIC( txt );
 
1088
 
 
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 ) );
 
1092
        }
 
1093
}
 
1094
#endif /*DEBUG*/
 
1095
 
 
1096
        /* Is this function call in the history?
 
1097
         */
 
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.
 
1101
                 */
 
1102
                g_object_unref( vi );
 
1103
                vi = old_vi;
 
1104
                g_object_ref( vi );
 
1105
 
 
1106
                if( trace_flags & TRACE_VIPS ) 
 
1107
                        vips_buf_appendf( trace_current(), "(from cache) " );
 
1108
 
 
1109
#ifdef DEBUG_HISTORY
 
1110
                printf( "vips_dispatch: found %s in history\n", vi->name );
 
1111
#endif /*DEBUG_HISTORY*/
 
1112
        }
 
1113
        else {
 
1114
                /* No: call function.
 
1115
                 */
 
1116
                int result;
 
1117
 
 
1118
#ifdef DEBUG_TIME
 
1119
                static GTimer *timer = NULL;
 
1120
 
 
1121
                if( !timer )
 
1122
                        timer = g_timer_new();
 
1123
                g_timer_reset( timer );
 
1124
#endif /*DEBUG_TIME*/
 
1125
 
 
1126
#ifdef DEBUG_HISTORY_MISS
 
1127
                printf( "vips_dispatch: calling %s\n", vi->name );
 
1128
#endif /*DEBUG_HISTORY_MISS*/
 
1129
 
 
1130
                /* Be careful. Eval callbacks from this may do anything,
 
1131
                 * including call vips_dispatch().
 
1132
                 */
 
1133
                result = vi->fn->disp( vi->vargv );
 
1134
 
 
1135
#ifdef DEBUG_TIME
 
1136
                printf( "vips_dispatch: %s - %g seconds\n", 
 
1137
                        vi->name, g_timer_elapsed( timer, NULL ) );
 
1138
#endif /*DEBUG_TIME*/
 
1139
 
 
1140
                if( result ) {
 
1141
                        vips_error_fn_vips( vi );
 
1142
                        g_object_unref( vi );
 
1143
                        return( NULL );
 
1144
                }
 
1145
                vips_update_hist( vi );
 
1146
        }
 
1147
 
 
1148
        /* Add to our operation cache, if necessary.
 
1149
         */
 
1150
        if( !(vi->fn->flags & IM_FN_NOCACHE) ) {
 
1151
                if( vi->in_cache ) 
 
1152
                        /* Already in the history. Just touch the time.
 
1153
                         */
 
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.
 
1158
                         */
 
1159
                        vips_history_touch( old_vi );
 
1160
                        vi = old_vi;
 
1161
                }
 
1162
                else
 
1163
                        vips_history_add( vi );
 
1164
        }
 
1165
 
 
1166
#ifdef DEBUG_HISTORY_SANITY
 
1167
        vips_history_sanity();
 
1168
#endif /*DEBUG_HISTORY_SANITY*/
 
1169
 
 
1170
        return( vi );
 
1171
}
 
1172