1 /* Manage pipelines of partial images.
2 *
3 * J.Cupitt, 17/4/93.
4 * 1/7/93 JC
5 * - adapted for partial v2
6 * - ANSIfied
7 * 6/7/93 JC
8 * - im_setupout() conventions clarified - see autorewind in
9 * im_iocheck().
10 * 20/7/93 JC
11 * - eval callbacks added
12 * 7/9/93 JC
13 * - demand hint mechanism added
14 * 25/10/93
15 * - asynchronous output mechanisms removed, as no observable speed-up
16 * 9/5/94
17 * - new thread stuff added, with a define to turn it off
18 * 15/8/94
19 * - start & stop functions can now be NULL for no-op
20 * 7/10/94 JC
21 * - evalend callback system added
22 * 23/12/94 JC
23 * - IM_ARRAY uses added
24 * 22/2/95 JC
25 * - im_fill_copy() added
26 * - im_region_region() uses modified
27 * 24/4/95 JC & KM
28 * - im_fill_lines() bug removed
29 * 30/8/96 JC
30 * - revised and simplified ... some code shared with im_iterate()
31 * - new im_generate_region() added
32 * 2/3/98 JC
33 * - IM_ANY added
34 * 20/7/99 JC
35 * - tile geometry made into ints for easy tuning
36 * 30/7/99 RP JC
37 * - threads reorganised for POSIX
38 * 29/9/99 JC
39 * - threadgroup stuff added
40 * 15/4/04
41 * - better how-many-pixels-calculated
42 * 27/11/06
43 * - merge background write stuff
44 * 7/11/07
45 * - new start/end eval callbacks
46 * 7/10/09
47 * - gtkdoc comments
48 * 16/4/10
49 * - remove threadgroup stuff
50 * 24/3/11
51 * - move demand_hint stuff in here
52 * - move to vips_ namespace
53 * 7/7/12
54 * - lock around link make/break so we can process an image from many
55 * threads
56 */
57
58 /*
59
60 This file is part of VIPS.
61
62 VIPS is free software; you can redistribute it and/or modify
63 it under the terms of the GNU Lesser General Public License as published by
64 the Free Software Foundation; either version 2 of the License, or
65 (at your option) any later version.
66
67 This program is distributed in the hope that it will be useful,
68 but WITHOUT ANY WARRANTY; without even the implied warranty of
69 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70 GNU Lesser General Public License for more details.
71
72 You should have received a copy of the GNU Lesser General Public License
73 along with this program; if not, write to the Free Software
74 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
75 02110-1301 USA
76
77 */
78
79 /*
80
81 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
82
83 */
84
85 /*
86 #define VIPS_DEBUG
87 #define DEBUG
88 */
89
90 #ifdef HAVE_CONFIG_H
91 #include <config.h>
92 #endif /*HAVE_CONFIG_H*/
93 #include <vips/intl.h>
94
95 #include <stdio.h>
96 #include <stdlib.h>
97 #include <stdarg.h>
98 #include <assert.h>
99 #include <errno.h>
100 #include <string.h>
101 #include <sys/types.h>
102 #ifdef HAVE_UNISTD_H
103 #include <unistd.h>
104 #endif /*HAVE_UNISTD_H*/
105 #ifdef HAVE_IO_H
106 #include <io.h>
107 #endif /*HAVE_IO_H*/
108
109 #include <vips/vips.h>
110 #include <vips/internal.h>
111 #include <vips/thread.h>
112 #include <vips/debug.h>
113
114 /**
115 * SECTION: generate
116 * @short_description: calculate pixels and pixel buffers
117 * @stability: Stable
118 * @see_also: <link linkend="VipsImage">VipsImage</link>,
119 * <link linkend="VipsRegion">VipsRegion</link>
120 * @include: vips/vips.h
121 *
122 * These functions let you attach generate functions to images
123 * and ask for regions of images to be calculated.
124 */
125
126 /* Max number of images we can handle.
127 */
128 #define MAX_IMAGES (1000)
129
130 /* Make an upstream/downstream link. upstream is one of downstream's inputs.
131 */
132 static void
vips__link_make(VipsImage * image_up,VipsImage * image_down)133 vips__link_make( VipsImage *image_up, VipsImage *image_down )
134 {
135 g_assert( image_up );
136 g_assert( image_down );
137
138 image_up->downstream =
139 g_slist_prepend( image_up->downstream, image_down );
140 image_down->upstream =
141 g_slist_prepend( image_down->upstream, image_up );
142
143 /* Propogate the progress indicator.
144 */
145 if( image_up->progress_signal &&
146 !image_down->progress_signal )
147 image_down->progress_signal = image_up->progress_signal;
148 }
149
150 static void *
vips__link_break(VipsImage * image_up,VipsImage * image_down,void * b)151 vips__link_break( VipsImage *image_up, VipsImage *image_down, void *b )
152 {
153 g_assert( image_up );
154 g_assert( image_down );
155
156 g_assert( g_slist_find( image_up->downstream, image_down ) );
157 g_assert( g_slist_find( image_down->upstream, image_up ) );
158
159 image_up->downstream =
160 g_slist_remove( image_up->downstream, image_down );
161 image_down->upstream =
162 g_slist_remove( image_down->upstream, image_up );
163
164 /* Unlink the progress chain.
165 */
166 if( image_down->progress_signal &&
167 image_down->progress_signal == image_up->progress_signal )
168 image_down->progress_signal = NULL;
169
170 return( NULL );
171 }
172
173 static void *
vips__link_break_rev(VipsImage * image_down,VipsImage * image_up,void * b)174 vips__link_break_rev( VipsImage *image_down, VipsImage *image_up, void *b )
175 {
176 return( vips__link_break( image_up, image_down, b ) );
177 }
178
179 /* A VipsImage is going ... break all links.
180 */
181 void
vips__link_break_all(VipsImage * image)182 vips__link_break_all( VipsImage *image )
183 {
184 g_mutex_lock( vips__global_lock );
185
186 vips_slist_map2( image->upstream,
187 (VipsSListMap2Fn) vips__link_break, image, NULL );
188 vips_slist_map2( image->downstream,
189 (VipsSListMap2Fn) vips__link_break_rev, image, NULL );
190
191 g_assert( !image->upstream );
192 g_assert( !image->downstream );
193
194 g_mutex_unlock( vips__global_lock );
195 }
196
197 typedef struct _LinkMap {
198 gboolean upstream;
199 int serial;
200 VipsSListMap2Fn fn;
201 void *a;
202 void *b;
203 } LinkMap;
204
205 static void *
vips__link_mapp(VipsImage * image,LinkMap * map,void * b)206 vips__link_mapp( VipsImage *image, LinkMap *map, void *b )
207 {
208 void *res;
209
210 /* Loop?
211 */
212 if( image->serial == map->serial )
213 return( NULL );
214 image->serial = map->serial;
215
216 if( (res = map->fn( image, map->a, map->b )) )
217 return( res );
218
219 return( vips_slist_map2( map->upstream ?
220 image->upstream : image->downstream,
221 (VipsSListMap2Fn) vips__link_mapp, map, NULL ) );
222 }
223
224 static void *
vips__link_map_cb(VipsImage * image,GSList ** images,void * b)225 vips__link_map_cb( VipsImage *image, GSList **images, void *b )
226 {
227 *images = g_slist_prepend( *images, image );
228
229 return( NULL );
230 }
231
232 /* Apply a function to an image and all upstream or downstream images,
233 * direct and indirect.
234 */
235 void *
vips__link_map(VipsImage * image,gboolean upstream,VipsSListMap2Fn fn,void * a,void * b)236 vips__link_map( VipsImage *image, gboolean upstream,
237 VipsSListMap2Fn fn, void *a, void *b )
238 {
239 static int serial = 0;
240
241 LinkMap map;
242 GSList *images;
243 GSList *p;
244 void *result;
245
246 images = NULL;
247
248 /* The function might do anything, including removing images
249 * or invalidating other images, so we can't trigger them from within
250 * the image loop. Instead we collect a list of images, ref them,
251 * run the functions, and unref.
252 */
253
254 map.upstream = upstream;
255 map.fn = (VipsSListMap2Fn) vips__link_map_cb;
256 map.a = (void *) &images;
257 map.b = NULL;
258
259 /* We will be walking the tree of images and updating the ->serial
260 * member. There will be intense confusion if two threads try to do
261 * this at the same time.
262 */
263 g_mutex_lock( vips__global_lock );
264
265 serial += 1;
266 map.serial = serial;
267
268 vips__link_mapp( image, &map, NULL );
269
270 for( p = images; p; p = p->next )
271 g_object_ref( p->data );
272
273 g_mutex_unlock( vips__global_lock );
274
275 result = vips_slist_map2( images, fn, a, b );
276
277 for( p = images; p; p = p->next )
278 g_object_unref( p->data );
279 g_slist_free( images );
280
281 return( result );
282 }
283
284 /* We have to have this as a separate entry point so we can support the old
285 * vips7 API.
286 */
287 void
vips__demand_hint_array(VipsImage * image,VipsDemandStyle hint,VipsImage ** in)288 vips__demand_hint_array( VipsImage *image,
289 VipsDemandStyle hint, VipsImage **in )
290 {
291 int i, len, nany;
292 VipsDemandStyle set_hint;
293
294 /* How many input images are there? And how many are ANY?
295 */
296 for( i = 0, len = 0, nany = 0; in[i]; i++, len++ )
297 if( in[i]->dhint == VIPS_DEMAND_STYLE_ANY )
298 nany++;
299
300 /* Find the most restrictive of all the hints available to us.
301 *
302 * We have tried to be smarter about this in the past -- for example,
303 * detecting all ANY inputs and ignoring the hint in this case, but
304 * there are inevitably odd cases which cause problems. For example,
305 * new_from_memory, resize, affine, write_to_memory would run with
306 * FATSTRIP.
307 */
308 set_hint = hint;
309 for( i = 0; i < len; i++ )
310 set_hint = (VipsDemandStyle) VIPS_MIN(
311 (int) set_hint, (int) in[i]->dhint );
312
313 image->dhint = set_hint;
314
315 #ifdef DEBUG
316 printf( "vips_image_pipeline_array: set dhint for \"%s\" to %s\n",
317 image->filename,
318 vips_enum_nick( VIPS_TYPE_DEMAND_STYLE, image->dhint ) );
319 printf( "\toperation requested %s\n",
320 vips_enum_nick( VIPS_TYPE_DEMAND_STYLE, hint ) );
321 printf( "\tinputs were:\n" );
322 printf( "\t" );
323 for( i = 0; in[i]; i++ )
324 printf( "%s ", vips_enum_nick( VIPS_TYPE_DEMAND_STYLE,
325 in[i]->dhint ) );
326 printf( "\n" );
327 #endif /*DEBUG*/
328
329 /* im depends on all these ims.
330 */
331 g_mutex_lock( vips__global_lock );
332 for( i = 0; i < len; i++ )
333 vips__link_make( in[i], image );
334 g_mutex_unlock( vips__global_lock );
335
336 /* Set a flag on the image to say we remembered to call this thing.
337 * vips_image_generate() and friends check this.
338 */
339 image->hint_set = TRUE;
340 }
341
342 /**
343 * vips_image_pipeline_array:
344 * @image: (out): output image
345 * @hint: demand hint for @image
346 * @in: (array zero-terminated=1): %NULL-terminated array of input images
347 *
348 * Add an image to a pipeline. @image depends on all of the images in @in,
349 * @image prefers to supply pixels according to @hint.
350 *
351 * Operations can set demand hints, that is, hints to the VIPS IO system about
352 * the type of region geometry they work best with. For example,
353 * operations which transform coordinates will usually work best with
354 * %VIPS_DEMAND_STYLE_SMALLTILE, operations which work on local windows of
355 * pixels will like %VIPS_DEMAND_STYLE_FATSTRIP.
356 *
357 * Header fields in @image are set from the fields in @in, with lower-numbered
358 * images in @in taking priority.
359 * For example, if @in[0] and @in[1] both have an item
360 * called "icc-profile", it's the profile attached to @in[0] that will end up
361 * on @image.
362 * Image history is completely copied from all @in. @image will have the history
363 * of all the input images.
364 * The array of input images can be empty, meaning @image is at the start of a
365 * pipeline.
366 *
367 * VIPS uses the list of input images to build the tree of operations it needs
368 * for the cache invalidation system.
369 *
370 * See also: vips_image_pipelinev(), vips_image_generate().
371 *
372 * Returns: 0 on success, -1 on error.
373 */
374 int
vips_image_pipeline_array(VipsImage * image,VipsDemandStyle hint,VipsImage ** in)375 vips_image_pipeline_array( VipsImage *image,
376 VipsDemandStyle hint, VipsImage **in )
377 {
378 /* This function can be called more than once per output image. For
379 * example, jpeg header load will call this once on ->out to set the
380 * default hint, then later call it again to connect the output image
381 * up to the real image.
382 *
383 * It's only ever called first time with in[0] == NULL and second time
384 * with a real value for @in.
385 */
386 vips__demand_hint_array( image, hint, in );
387
388 if( in[0] &&
389 vips__image_copy_fields_array( image, in ) )
390 return( -1 );
391
392 if( vips__reorder_set_input( image, in ) )
393 return( -1 );
394
395 return( 0 );
396 }
397
398 /**
399 * vips_image_pipelinev:
400 * @image: output image of pipeline
401 * @hint: hint for this image
402 * @...: %NULL-terminated list of input images
403 *
404 * Build an array and call vips_image_pipeline_array().
405 *
406 * See also: vips_image_generate().
407 */
408 int
vips_image_pipelinev(VipsImage * image,VipsDemandStyle hint,...)409 vips_image_pipelinev( VipsImage *image, VipsDemandStyle hint, ... )
410 {
411 va_list ap;
412 int i;
413 VipsImage *ar[MAX_IMAGES];
414
415 va_start( ap, hint );
416 for( i = 0; i < MAX_IMAGES &&
417 (ar[i] = va_arg( ap, VipsImage * )); i++ )
418 ;
419 va_end( ap );
420 if( i == MAX_IMAGES ) {
421 g_warning( "%s", _( "too many images" ) );
422
423 /* Make sure we have a sentinel there.
424 */
425 ar[i - 1] = NULL;
426 }
427
428 return( vips_image_pipeline_array( image, hint, ar ) );
429 }
430
431 /**
432 * vips_start_one:
433 * @out: image to generate
434 * @a: user data
435 * @b: user data
436 *
437 * Start function for one image in. Input image is @a.
438 *
439 * See also: vips_image_generate().
440 */
441 void *
vips_start_one(VipsImage * out,void * a,void * b)442 vips_start_one( VipsImage *out, void *a, void *b )
443 {
444 VipsImage *in = (VipsImage *) a;
445
446 return( vips_region_new( in ) );
447 }
448
449 /**
450 * vips_stop_one:
451 * @seq: sequence value
452 * @a: user data
453 * @b: user data
454 *
455 * Stop function for one image in. Input image is @a.
456 *
457 * See also: vips_image_generate().
458 */
459 int
vips_stop_one(void * seq,void * a,void * b)460 vips_stop_one( void *seq, void *a, void *b )
461 {
462 VipsRegion *reg = (VipsRegion *) seq;
463
464 g_object_unref( reg );
465
466 return( 0 );
467 }
468
469 /**
470 * vips_stop_many:
471 * @seq: sequence value
472 * @a: user data
473 * @b: user data
474 *
475 * Stop function for many images in. @a is a pointer to
476 * a %NULL-terminated array of input images.
477 *
478 * See also: vips_image_generate().
479 */
480 int
vips_stop_many(void * seq,void * a,void * b)481 vips_stop_many( void *seq, void *a, void *b )
482 {
483 VipsRegion **ar = (VipsRegion **) seq;
484
485 if( ar ) {
486 int i;
487
488 for( i = 0; ar[i]; i++ )
489 g_object_unref( ar[i] );
490 g_free( (char *) ar );
491 }
492
493 return( 0 );
494 }
495
496 /**
497 * vips_start_many:
498 * @out: image to generate
499 * @a: user data
500 * @b: user data
501 *
502 * Start function for many images in. @a is a pointer to
503 * a %NULL-terminated array of input images.
504 *
505 * See also: vips_image_generate(), vips_allocate_input_array()
506 */
507 void *
vips_start_many(VipsImage * out,void * a,void * b)508 vips_start_many( VipsImage *out, void *a, void *b )
509 {
510 VipsImage **in = (VipsImage **) a;
511
512 int i, n;
513 VipsRegion **ar;
514
515 /* How many images?
516 */
517 for( n = 0; in[n]; n++ )
518 ;
519
520 /* Alocate space for region array.
521 */
522 if( !(ar = VIPS_ARRAY( NULL, n + 1, VipsRegion * )) )
523 return( NULL );
524
525 /* Create a set of regions.
526 */
527 for( i = 0; i < n; i++ )
528 if( !(ar[i] = vips_region_new( in[i] )) ) {
529 vips_stop_many( ar, NULL, NULL );
530 return( NULL );
531 }
532 ar[n] = NULL;
533
534 return( ar );
535 }
536
537 /**
538 * vips_allocate_input_array:
539 * @out: free array when this image closes
540 * @...: %NULL-terminated list of input images
541 *
542 * Convenience function --- make a %NULL-terminated array of input images.
543 * Use with vips_start_many().
544 *
545 * See also: vips_image_generate(), vips_start_many().
546 *
547 * Returns: %NULL-terminated array of images. Do not free the result.
548 */
549 VipsImage **
vips_allocate_input_array(VipsImage * out,...)550 vips_allocate_input_array( VipsImage *out, ... )
551 {
552 va_list ap;
553 VipsImage **ar;
554 int i, n;
555
556 /* Count input images.
557 */
558 va_start( ap, out );
559 for( n = 0; va_arg( ap, VipsImage * ); n++ )
560 ;
561 va_end( ap );
562
563 /* Allocate array.
564 */
565 if( !(ar = VIPS_ARRAY( out, n + 1, VipsImage * )) )
566 return( NULL );
567
568 /* Fill array.
569 */
570 va_start( ap, out );
571 for( i = 0; i < n; i++ )
572 ar[i] = va_arg( ap, VipsImage * );
573 va_end( ap );
574 ar[n] = NULL;
575
576 return( ar );
577 }
578
579 /**
580 * VipsStartFn:
581 * @out: image being calculated
582 * @a: user data
583 * @b: user data
584 *
585 * Start a new processing sequence for this generate function. This allocates
586 * per-thread state, such as an input region.
587 *
588 * See also: vips_start_one(), vips_start_many().
589 *
590 * Returns: a new sequence value
591 */
592
593 /**
594 * VipsGenerateFn:
595 * @out: #VipsRegion to fill
596 * @seq: sequence value
597 * @a: user data
598 * @b: user data
599 * @stop: set this to stop processing
600 *
601 * Fill @out->valid with pixels. @seq contains per-thread state, such as the
602 * input regions. Set @stop to %TRUE to stop processing.
603 *
604 * See also: vips_image_generate(), vips_stop_many().
605 *
606 * Returns: 0 on success, -1 on error.
607 */
608
609 /**
610 * VipsStopFn:
611 * @seq: sequence value
612 * @a: user data
613 * @b: user data
614 *
615 * Stop a processing sequence. This frees
616 * per-thread state, such as an input region.
617 *
618 * See also: vips_stop_one(), vips_stop_many().
619 *
620 * Returns: 0 on success, -1 on error.
621 */
622
623 /* A write function for VIPS images. Just write() the pixel data.
624 */
625 static int
write_vips(VipsRegion * region,VipsRect * area,void * a)626 write_vips( VipsRegion *region, VipsRect *area, void *a )
627 {
628 size_t nwritten, count;
629 void *buf;
630
631 count = (size_t) region->bpl * area->height;
632 buf = VIPS_REGION_ADDR( region, 0, area->top );
633
634 do {
635 nwritten = write( region->im->fd, buf, count );
636 if( nwritten == (size_t) -1 )
637 return( errno );
638
639 buf = (void *) ((char *) buf + nwritten);
640 count -= nwritten;
641 } while( count > 0 );
642
643 return( 0 );
644 }
645
646 /**
647 * vips_image_generate:
648 * @image: generate this image
649 * @start_fn: start sequences with this function
650 * @generate_fn: generate pixels with this function
651 * @stop_fn: stop sequences with this function
652 * @a: user data
653 * @b: user data
654 *
655 * Generates an image. The action depends on the image type.
656 *
657 * For images created with vips_image_new(), vips_image_generate() just
658 * attaches the start/generate/stop callbacks and returns.
659 *
660 * For images created with vips_image_new_memory(), memory is allocated for
661 * the whole image and it is entirely generated using vips_sink_memory().
662 *
663 * For images created with vips_image_new_temp_file() and friends, memory for
664 * a few scanlines is allocated and
665 * vips_sink_disc() used to generate the image in small chunks. As each
666 * chunk is generated, it is written to disc.
667 *
668 * See also: vips_sink(), vips_image_new(), vips_region_prepare().
669 *
670 * Returns: 0 on success, or -1 on error.
671 */
672 int
vips_image_generate(VipsImage * image,VipsStartFn start_fn,VipsGenerateFn generate_fn,VipsStopFn stop_fn,void * a,void * b)673 vips_image_generate( VipsImage *image,
674 VipsStartFn start_fn, VipsGenerateFn generate_fn, VipsStopFn stop_fn,
675 void *a, void *b )
676 {
677 int res;
678
679 VIPS_DEBUG_MSG( "vips_image_generate: %p\n", image );
680
681 g_assert( generate_fn );
682 g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
683
684 if( !image->hint_set ) {
685 vips_error( "vips_image_generate",
686 "%s", _( "demand hint not set" ) );
687 return( -1 );
688 }
689
690 /* We don't use this, but make sure it's set in case any old binaries
691 * are expecting it.
692 */
693 image->Bbits = vips_format_sizeof( image->BandFmt ) << 3;
694
695 /* Look at output type to decide our action.
696 */
697 switch( image->dtype ) {
698 case VIPS_IMAGE_PARTIAL:
699 /* Output to partial image. Just attach functions and return.
700 */
701 if( image->generate_fn ||
702 image->start_fn ||
703 image->stop_fn ) {
704 vips_error( "VipsImage",
705 "%s", _( "generate() called twice" ) );
706 return( -1 );
707 }
708
709 image->start_fn = start_fn;
710 image->generate_fn = generate_fn;
711 image->stop_fn = stop_fn;
712 image->client1 = a;
713 image->client2 = b;
714
715 VIPS_DEBUG_MSG( "vips_image_generate: "
716 "attaching partial callbacks\n" );
717
718 if( vips_image_written( image ) )
719 return( -1 );
720
721 break;
722
723 case VIPS_IMAGE_SETBUF:
724 case VIPS_IMAGE_SETBUF_FOREIGN:
725 case VIPS_IMAGE_MMAPINRW:
726 case VIPS_IMAGE_OPENOUT:
727 /* Eval now .. sanity check.
728 */
729 if( image->generate_fn ||
730 image->start_fn ||
731 image->stop_fn ) {
732 vips_error( "VipsImage",
733 "%s", _( "generate() called twice" ) );
734 return( -1 );
735 }
736
737 /* Attach callbacks.
738 */
739 image->start_fn = start_fn;
740 image->generate_fn = generate_fn;
741 image->stop_fn = stop_fn;
742 image->client1 = a;
743 image->client2 = b;
744
745 if( vips_image_write_prepare( image ) )
746 return( -1 );
747
748 if( image->dtype == VIPS_IMAGE_OPENOUT )
749 res = vips_sink_disc( image, write_vips, NULL );
750 else
751 res = vips_sink_memory( image );
752
753 /* Error?
754 */
755 if( res )
756 return( -1 );
757
758 /* Must come before we rewind.
759 */
760 if( vips_image_written( image ) )
761 return( -1 );
762
763 /* We've written to image ... rewind it ready for reading.
764 */
765 if( vips_image_pio_input( image ) )
766 return( -1 );
767
768 break;
769
770 default:
771 /* Not a known output style.
772 */
773 vips_error( "VipsImage",
774 _( "unable to output to a %s image" ),
775 vips_enum_nick( VIPS_TYPE_IMAGE_TYPE,
776 image->dtype ) );
777 return( -1 );
778 }
779
780 return( 0 );
781 }
782