stuff
This commit is contained in:
parent
cc68842434
commit
a584569881
@ -51,11 +51,12 @@
|
||||
- added im_flood_other() as start of simple segmentation operator
|
||||
- added im_segment()
|
||||
- im_printlines(), im_debugim() deprecated (use im_vips2csv() instead)
|
||||
- meta, header, callback, error, REGION gtkdocs
|
||||
- meta, header, callback, error, region gtkdocs
|
||||
- removed printlines tool, vips2csv is much better
|
||||
- removed other useless tools as well: debugim, binfile
|
||||
- fix up addr calcs on 64-bit machines with >2gb images and inplace ops
|
||||
(thanks Christoph)
|
||||
- im_generate() checks that im_demand_hint() has been called for this image
|
||||
|
||||
25/3/09 started 7.18.0
|
||||
- revised version numbers
|
||||
|
9
TODO
9
TODO
@ -1,8 +1,11 @@
|
||||
- reached im_iterate() in region.h
|
||||
- region needs to be broken up
|
||||
|
||||
split prepare, generate etc. out to another chapter, maybe generate.h
|
||||
|
||||
|
||||
- VipsFormat next? where should we document the im_vip2jpeg() options?
|
||||
|
||||
|
||||
- inplace ops break over 2gb? insert_inplace especially
|
||||
|
||||
- more stuff from util.c? too much to do it all now
|
||||
|
||||
- im_render()?
|
||||
|
@ -22,6 +22,7 @@
|
||||
<xi:include href="xml/callback.xml"/>
|
||||
<xi:include href="xml/error.xml"/>
|
||||
<xi:include href="xml/meta.xml"/>
|
||||
<xi:include href="xml/region.xml"/>
|
||||
<xi:include href="xml/buf.xml"/>
|
||||
</chapter>
|
||||
|
||||
@ -39,7 +40,6 @@
|
||||
<xi:include href="xml/object.xml"/>
|
||||
<xi:include href="xml/proto.xml"/>
|
||||
<xi:include href="xml/colour.xml"/>
|
||||
<xi:include href="xml/region.xml"/>
|
||||
<xi:include href="xml/transform.xml"/>
|
||||
<xi:include href="xml/util.xml"/>
|
||||
<xi:include href="xml/threadgroup.xml"/>
|
||||
|
@ -41,6 +41,17 @@
|
||||
#include <dmalloc.h>
|
||||
#endif /*WITH_DMALLOC*/
|
||||
|
||||
/**
|
||||
* SECTION: VipsFormat
|
||||
* @short_description: load and save in a variety of formats
|
||||
* @stability: Stable
|
||||
* @see_also: <link linkend="libvips-image">image</link>
|
||||
* @include: vips/vips.h
|
||||
*
|
||||
* VIPS has a simple system for representing image loader
|
||||
*
|
||||
*/
|
||||
|
||||
/* To iterate over supported formats, we build a temp list of subclasses of
|
||||
* VipsFormat, sort by priority, iterate, and free.
|
||||
*/
|
||||
|
@ -198,6 +198,12 @@ typedef struct _VipsImage {
|
||||
/* Parent/child relationships, built from args to im_demand_hint().
|
||||
* We use these to invalidate pixel buffers on im_invalidate(). Use
|
||||
* 'serial' to spot circular dependencies.
|
||||
*
|
||||
* Parents are later in the tree, so it's child1 + child2 -> parent,
|
||||
* for example. On im_invalidate(), we dispose the caches on all
|
||||
* parents of an image.
|
||||
*
|
||||
* See also hint_set below.
|
||||
*/
|
||||
GSList *parents;
|
||||
GSList *children;
|
||||
@ -223,6 +229,14 @@ typedef struct _VipsImage {
|
||||
* been truncated.
|
||||
*/
|
||||
size_t file_length;
|
||||
|
||||
/* Set this when im_demand_hint_array() is called, and check in any
|
||||
* operation that will demand pixels from the image.
|
||||
*
|
||||
* We use im_demand_hint_array() to build the tree of parent/child
|
||||
* relationships, so it's a mandatory thing.
|
||||
*/
|
||||
gboolean hint_set;
|
||||
} VipsImage;
|
||||
|
||||
/* Pixel address calculation macros.
|
||||
|
@ -81,9 +81,9 @@ int im_region_position( REGION *reg1, int x, int y );
|
||||
int im_prepare( REGION *reg, Rect *r );
|
||||
int im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y );
|
||||
|
||||
typedef void *(*im_start_fn)( IMAGE *, void *, void * );
|
||||
typedef int (*im_generate_fn)( REGION *, void *, void *, void *);
|
||||
typedef int (*im_stop_fn)( void *, void *, void * );
|
||||
typedef void *(*im_start_fn)( IMAGE *out, void *a, void *b );
|
||||
typedef int (*im_generate_fn)( REGION *out, void *seq, void *a, void *b );
|
||||
typedef int (*im_stop_fn)( void *seq, void *a, void *b );
|
||||
|
||||
void *im_start_one( IMAGE *out, void *in, void *dummy );
|
||||
int im_stop_one( void *seq, void *dummy1, void *dummy2 );
|
||||
@ -101,12 +101,9 @@ int im_iterate( IMAGE *im,
|
||||
void *a, void *b
|
||||
);
|
||||
|
||||
int im_demand_hint_array( IMAGE *im, im_demand_type hint, IMAGE **in );
|
||||
int im_demand_hint( IMAGE *im, im_demand_type hint, ... )
|
||||
__attribute__((sentinel));
|
||||
int im_demand_hint_array( IMAGE *im, im_demand_type hint, IMAGE **in );
|
||||
|
||||
void im_free_region_array( REGION **regs );
|
||||
REGION **im_allocate_region_array( IMAGE *im, int count );
|
||||
|
||||
/* Buffer processing.
|
||||
*/
|
||||
|
@ -35,7 +35,6 @@ libiofuncs_la_SOURCES = \
|
||||
im_guess_prefix.c \
|
||||
im_wbuffer.c \
|
||||
im_wrapmany.c \
|
||||
im_wraptwo.c \
|
||||
im_writeline.c \
|
||||
memory.c \
|
||||
package.c \
|
||||
|
@ -1,54 +1,4 @@
|
||||
/* @(#) Hint to the evaluation mechanism that it should ask for output from
|
||||
* @(#) this image with a certain shape of patch.
|
||||
* @(#)
|
||||
* @(#) int
|
||||
* @(#) im_demand_hint( im, hint, in1, in2, ..., NULL )
|
||||
* @(#) IMAGE *im, *in1, *in2, ...;
|
||||
* @(#) im_demand_type hint;
|
||||
* @(#)
|
||||
* @(#) hint may be one of
|
||||
* @(#)
|
||||
* @(#) IM_THINSTRIP
|
||||
* @(#) This operation would like to output strips the width of the
|
||||
* @(#) image and a few pels high. This is option suitable for
|
||||
* @(#) point-to-point operations, such as those in the arithmetic
|
||||
* @(#) package.
|
||||
* @(#)
|
||||
* @(#) This is the fastest style for most simple operations.
|
||||
* @(#)
|
||||
* @(#) IM_FATSTRIP
|
||||
* @(#) This operation would like to output strips the width of the
|
||||
* @(#) image and as high as possible. This option is suitable for
|
||||
* @(#) area operations which do not violently transform coordinates,
|
||||
* @(#) such as im_conv().
|
||||
* @(#)
|
||||
* @(#) IM_SMALLTILE
|
||||
* @(#) This is the most general demand format, and is the default.
|
||||
* @(#) Output is demanded in small (around 100x100 pel) sections.
|
||||
* @(#) This style works reasonably efficiently, even for bizzare
|
||||
* @(#) operations like 45 degree rotate.
|
||||
* @(#)
|
||||
* @(#) IM_ANY
|
||||
* @(#) Not from a disc file, so any geometry is OK.
|
||||
* @(#)
|
||||
* @(#) NOTE: demand style falls back to the most restrictive in the pipeline.
|
||||
* @(#) All pipeline elements in the pipeline must agree on IM_THINSTRIP
|
||||
* @(#) before output will be asked for in this manner. If you do not set a
|
||||
* @(#) hint, you will get IM_SMALLTILE.
|
||||
* @(#)
|
||||
* @(#) in1, in2, ... are the images on which out will make demands. You
|
||||
* @(#) should terminate the list with NULL.
|
||||
* @(#)
|
||||
* @(#) int
|
||||
* @(#) im_demand_hint_array( im, hint, in )
|
||||
* @(#) IMAGE *im, **in;
|
||||
* @(#) im_demand_type hint;
|
||||
* @(#)
|
||||
* @(#) As above, but in is a NULL-terminated array of input images. Use
|
||||
* @(#) im_allocate_input_array() to build the input array.
|
||||
* @(#)
|
||||
* @(#) Returns non-zero on failure.
|
||||
* @(#)
|
||||
/* demand hints
|
||||
*
|
||||
* Copyright: The National Gallery, 1993
|
||||
* Written on: 6/9/93
|
||||
@ -60,6 +10,8 @@
|
||||
* fails for image import
|
||||
* 1/12/06
|
||||
* - build parent/child links as well
|
||||
* 8/10/09
|
||||
* - gtkdoc comments
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -120,10 +72,28 @@ find_least( im_demand_type a, im_demand_type b )
|
||||
return( (im_demand_type) IM_MIN( (int) a, (int) b ) );
|
||||
}
|
||||
|
||||
/* Set hint for this image.
|
||||
/**
|
||||
* im_demand_hint_array:
|
||||
* @im: image to set hint for
|
||||
* @hint: hint for this image
|
||||
* @in: array of input images to this operation
|
||||
*
|
||||
* Operations can set demand hints, that is, hints to the VIPS IO system about
|
||||
* the type of region geometry this operation works best with. For example,
|
||||
* operations which transform coordinates will usually work best with
|
||||
* %IM_SMALLTILE, operations which work on local windows of pixels will like
|
||||
* %IM_FATSTRIP.
|
||||
*
|
||||
* VIPS uses the list of input images to build the tree of operations it needs
|
||||
* for the cache invalidation system. You have to call this function, or its
|
||||
* varargs friend im_demand_hint().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*
|
||||
* See also: im_demand_hint(), im_generate().
|
||||
*/
|
||||
int
|
||||
im_demand_hint_array( IMAGE *im, im_demand_type hint, IMAGE **in )
|
||||
im_demand_hint_array( IMAGE *im, VipsDemandStyle hint, IMAGE **in )
|
||||
{
|
||||
int i, len, nany;
|
||||
|
||||
@ -163,13 +133,28 @@ im_demand_hint_array( IMAGE *im, im_demand_type hint, IMAGE **in )
|
||||
for( i = 0; i < len; i++ )
|
||||
im__link_make( im, in[i] );
|
||||
|
||||
/* Set a flag on the image to say we remember to call this thing.
|
||||
* im_generate() and friends check this.
|
||||
*/
|
||||
im->hint_set = TRUE;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Build an array, and call the above.
|
||||
/**
|
||||
* im_demand_hint:
|
||||
* @im: image to set hint for
|
||||
* @hint: hint for this image
|
||||
* @Varargs: %NULL-terminated list of input images to this operation
|
||||
*
|
||||
* Build an array and call im_demand_hint_array().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*
|
||||
* See also: im_demand_hint(), im_generate().
|
||||
*/
|
||||
int
|
||||
im_demand_hint( IMAGE *im, im_demand_type hint, ... )
|
||||
im_demand_hint( IMAGE *im, VipsDemandStyle hint, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int i;
|
||||
|
@ -239,6 +239,49 @@ im_allocate_input_array( IMAGE *out, ... )
|
||||
return( ar );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_start_fn:
|
||||
* @out: image being calculated
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Start a new processing sequence for this generate function. This allocates
|
||||
* per-thread state, such as an input region.
|
||||
*
|
||||
* See also: im_start_one(), im_start_many().
|
||||
*
|
||||
* Returns: a new sequence value
|
||||
*/
|
||||
|
||||
/**
|
||||
* im_generate_fn:
|
||||
* @out: #REGION to fill
|
||||
* @seq: sequence value
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Fill @out->valid with pixels. @seq contains per-thread state, such as the
|
||||
* input regions.
|
||||
*
|
||||
* See also: im_generate(), im_stop_many().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
|
||||
/**
|
||||
* im_stop_fn:
|
||||
* @seq: sequence value
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Stop a processing sequence. This frees
|
||||
* per-thread state, such as an input region.
|
||||
*
|
||||
* See also: im_stop_one(), im_stop_many().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
|
||||
/* Loop over a big region, filling it in many small pieces with threads.
|
||||
*/
|
||||
static int
|
||||
@ -437,6 +480,12 @@ im_generate( IMAGE *im,
|
||||
|
||||
g_assert( !im_image_sanity( im ) );
|
||||
|
||||
if( !im->hint_set ) {
|
||||
im_error( "im_generate",
|
||||
"%s", _( "im_demand_hint() not set" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) {
|
||||
im_error( "im_generate",
|
||||
"%s", _( "bad dimensions" ) );
|
||||
|
@ -33,6 +33,8 @@
|
||||
* - lock global image list (thanks lee)
|
||||
* 19/3/09
|
||||
* - add file_length
|
||||
* 8/10/09
|
||||
* - add set_hint
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -172,6 +174,8 @@ im_init( const char *filename )
|
||||
|
||||
im->file_length = 0;
|
||||
|
||||
im->hint_set = FALSE;
|
||||
|
||||
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
||||
im_close( im );
|
||||
return( NULL );
|
||||
|
@ -193,7 +193,22 @@ iterate( im_threadgroup_t *tg, IMAGE *im,
|
||||
return( res );
|
||||
}
|
||||
|
||||
/* Scan region over image in small pieces.
|
||||
/**
|
||||
* im_iterate:
|
||||
* @im: scan over this image
|
||||
* @start: start sequences with this function
|
||||
* @generate: generate pixels with this function
|
||||
* @stop: stop sequences with this function
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Loops over an image. @generate is called for every pixel in the image, with
|
||||
* the @reg argument being a region of pixels for processing. im_iterate() is
|
||||
* used to implement operations like im_avg() which have no image output.
|
||||
*
|
||||
* See also: im_generate(), im_open().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
im_iterate( IMAGE *im,
|
||||
|
@ -270,7 +270,8 @@ im_prepare_to_generate( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/** im_prepare_to:
|
||||
/**
|
||||
* im_prepare_to:
|
||||
* @reg: region to prepare
|
||||
* @dest: region to write to
|
||||
* @r: #Rect of pixels you need to be able to address
|
||||
|
@ -1,20 +1,4 @@
|
||||
/* Wrap-up a buffer processing function as a PIO VIPS function.
|
||||
*
|
||||
* Given a NULL-terminated list of input images all of the same size, an
|
||||
* output image and a buffer processing function, make a PIO image processing
|
||||
* operation.
|
||||
*
|
||||
* int im_wrapmany( IMAGE **in, IMAGE *out,
|
||||
* im_wrapmany_fn fn, void *a, void *b )
|
||||
*
|
||||
* where im_wrapmany_fn has type:
|
||||
*
|
||||
* process_buffer( void **in, void *out, int n,
|
||||
* void *a, void *b )
|
||||
*
|
||||
* in is a NULL-terminated array of input buffers, out is an output buffer, n
|
||||
* is the number of pixels (note! not band-elements) and a and b are extra
|
||||
* arguments carried for the function
|
||||
/* wrapmany
|
||||
*
|
||||
* Modified:
|
||||
* 1/8/95 JC
|
||||
@ -24,6 +8,9 @@
|
||||
* - amazing error ... only worked if ir and or had same valid
|
||||
* 23/1/08
|
||||
* - do im_wrapone() in terms of this
|
||||
* 8/10/09
|
||||
* - gtkdoc comments
|
||||
* - move im_wraptwo in here
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -150,7 +137,34 @@ dupims( IMAGE *out, IMAGE **in )
|
||||
return( new );
|
||||
}
|
||||
|
||||
/* Wrap up as a partial.
|
||||
/**
|
||||
* im_wrapmany_fn:
|
||||
* @in: %NULL-terminated array of input buffers
|
||||
* @out: write processed pixels here
|
||||
* @width: number of pixels in buffer
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Given an array of buffers of input pixels, write a buffer of output pixels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* im_wrapmany:
|
||||
* @in: %NULL-terminated array of input images
|
||||
* @out: image to generate
|
||||
* @fn: buffer-processing function
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Wrap-up a buffer processing function as a PIO VIPS function.
|
||||
*
|
||||
* Given a NULL-terminated list of input images all of the same size, an
|
||||
* output image and a buffer processing function, make a PIO image processing
|
||||
* operation.
|
||||
*
|
||||
* See also: im_wrapone(), im_wraptwo(), im_generate().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
im_wrapmany( IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b )
|
||||
@ -212,6 +226,35 @@ wrapone_gen( void **ins, void *out, int width, Bundle *bun, void *dummy )
|
||||
((im_wrapone_fn) (bun->fn)) (ins[0], out, width, bun->a, bun->b );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_wrapone_fn:
|
||||
* @in: input pixels
|
||||
* @out: write processed pixels here
|
||||
* @width: number of pixels in buffer
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Given a buffer of input pixels, write a buffer of output pixels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* im_wrapone:
|
||||
* @in: input image
|
||||
* @out: image to generate
|
||||
* @fn: buffer-processing function
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Wrap-up a buffer processing function as a PIO VIPS function.
|
||||
*
|
||||
* Given an input image, an
|
||||
* output image and a buffer processing function, make a PIO image processing
|
||||
* operation.
|
||||
*
|
||||
* See also: im_wrapmany(), im_wraptwo(), im_generate().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
im_wrapone( IMAGE *in, IMAGE *out, im_wrapone_fn fn, void *a, void *b )
|
||||
{
|
||||
@ -229,17 +272,44 @@ im_wrapone( IMAGE *in, IMAGE *out, im_wrapone_fn fn, void *a, void *b )
|
||||
(im_wrapmany_fn) wrapone_gen, bun, NULL ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
commented out for now ... replace im_wraptwo with this?
|
||||
|
||||
static void
|
||||
wraptwo_gen( void **ins, void *out, int width, Bundle *bun, void *dummy )
|
||||
{
|
||||
((im_wraptwo_fn) (bun->fn)) (ins[0], ins[1], or,
|
||||
((im_wraptwo_fn) (bun->fn)) (ins[0], ins[1], out,
|
||||
width, bun->a, bun->b );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_wraptwo_fn:
|
||||
* @in1: input pixels from image 1
|
||||
* @in2: input pixels from image 2
|
||||
* @out: write processed pixels here
|
||||
* @width: number of pixels in buffer
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Given a pair of buffers of input pixels, write a buffer of output pixels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* im_wraptwo:
|
||||
* @in1: first input image
|
||||
* @in2: second input image
|
||||
* @out: image to generate
|
||||
* @fn: buffer-processing function
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
*
|
||||
* Wrap-up a buffer processing function as a PIO VIPS function.
|
||||
*
|
||||
* Given a pair of input images of the same size, an
|
||||
* output image and a buffer processing function, make a PIO image processing
|
||||
* operation.
|
||||
*
|
||||
* See also: im_wrapone(), im_wrapmany(), im_generate().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
im_wraptwo( IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
im_wraptwo_fn fn, void *a, void *b )
|
||||
@ -255,5 +325,3 @@ im_wraptwo( IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
return( im_wrapmany( invec, out,
|
||||
(im_wrapmany_fn) wraptwo_gen, bun, NULL ) );
|
||||
}
|
||||
|
||||
*/
|
||||
|
@ -1,103 +0,0 @@
|
||||
/* As im_wrapmany, but just allow one input and one output.
|
||||
*
|
||||
* The types become:
|
||||
*
|
||||
* int im_wrapone( IMAGE *in, IMAGE *out,
|
||||
* im_wrapone_fn fn, void *a, void *b )
|
||||
*
|
||||
* where im_wrapone_fn has type:
|
||||
*
|
||||
* process_buffer( void *in, void *out, int n,
|
||||
* void *a, void *b )
|
||||
* 28/7/97 JC
|
||||
* - amazing error ... failed if or and ir were different sizes
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#ifdef WITH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif /*WITH_DMALLOC*/
|
||||
|
||||
typedef struct {
|
||||
im_wraptwo_fn fn; /* Function we call */
|
||||
void *a, *b; /* User values for function */
|
||||
} UserBundle;
|
||||
|
||||
/* Build or->valid a line at a time from ir.
|
||||
*/
|
||||
static int
|
||||
process_region( REGION *or, void *seq, void *unrequired, void *b )
|
||||
{
|
||||
if( im_prepare_many( (REGION**)seq, & or-> valid ))
|
||||
return -1;
|
||||
{
|
||||
void *out= IM_REGION_ADDR_TOPLEFT( or );
|
||||
void *in1= IM_REGION_ADDR( ((REGION**)seq)[0], or-> valid. left, or-> valid. top );
|
||||
void *in2= IM_REGION_ADDR( ((REGION**)seq)[1], or-> valid. left, or-> valid. top );
|
||||
size_t out_skip= IM_REGION_LSKIP( or );
|
||||
size_t in1_skip= IM_REGION_LSKIP( ((REGION**)seq)[0] );
|
||||
size_t in2_skip= IM_REGION_LSKIP( ((REGION**)seq)[1] );
|
||||
void *out_stop= out + out_skip * or-> valid. height;
|
||||
|
||||
for( ; out < out_stop; out+= out_skip, in1+= in1_skip, in2+= in2_skip )
|
||||
((UserBundle*) b)-> fn( in1, in2, out, or-> valid. width, ((UserBundle*) b)-> a, ((UserBundle*) b)-> b );
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wrap up as a partial.
|
||||
*/
|
||||
int
|
||||
im_wraptwo( IMAGE *in1, IMAGE *in2, IMAGE *out, im_wraptwo_fn fn, void *a, void *b )
|
||||
{
|
||||
if( im_pincheck( in1 ) || im_pincheck( in2 ) || im_poutcheck( out ))
|
||||
return -1;
|
||||
{
|
||||
UserBundle *bun= IM_NEW( out, UserBundle );
|
||||
IMAGE **ins= im_allocate_input_array( out, in1, in2, NULL );
|
||||
|
||||
if( ! bun || ! ins )
|
||||
return -1;
|
||||
|
||||
bun-> fn= fn;
|
||||
bun-> a= a;
|
||||
bun-> b= b;
|
||||
|
||||
return im_demand_hint( out, IM_THINSTRIP, in1, in2, NULL )
|
||||
|| im_generate( out, im_start_many, process_region, im_stop_many, (void*) ins, (void*) bun );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user