add composite2 class
so we have a nice CLI interface to the new operator
This commit is contained in:
parent
df28948b9d
commit
14fd2af396
@ -2,6 +2,8 @@
|
|||||||
*
|
*
|
||||||
* 25/9/17
|
* 25/9/17
|
||||||
* - from bandjoin.c
|
* - from bandjoin.c
|
||||||
|
* 30/11/17
|
||||||
|
* - add composite2 class, to make a nice CLI interface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -91,7 +93,7 @@
|
|||||||
* VIPS_BLEND_MODE_DIFFERENCE:
|
* VIPS_BLEND_MODE_DIFFERENCE:
|
||||||
* VIPS_BLEND_MODE_EXCLUSION:
|
* VIPS_BLEND_MODE_EXCLUSION:
|
||||||
*
|
*
|
||||||
* The various Porter-Duff and PDF blend modes. See vips_composite(),
|
* The various Porter-Duff and PDF blend modes. See vips_composite_base(),
|
||||||
* for example.
|
* for example.
|
||||||
*
|
*
|
||||||
* The Cairo docs have a nice explanation of all the blend modes:
|
* The Cairo docs have a nice explanation of all the blend modes:
|
||||||
@ -107,7 +109,7 @@
|
|||||||
typedef float v4f __attribute__((vector_size(4 * sizeof(float))));
|
typedef float v4f __attribute__((vector_size(4 * sizeof(float))));
|
||||||
#endif /*HAVE_VECTOR_ARITH*/
|
#endif /*HAVE_VECTOR_ARITH*/
|
||||||
|
|
||||||
typedef struct _VipsComposite {
|
typedef struct _VipsCompositeBase {
|
||||||
VipsConversion parent_instance;
|
VipsConversion parent_instance;
|
||||||
|
|
||||||
/* The input images.
|
/* The input images.
|
||||||
@ -147,20 +149,38 @@ typedef struct _VipsComposite {
|
|||||||
v4f max_band_vec;
|
v4f max_band_vec;
|
||||||
#endif /*HAVE_VECTOR_ARITH*/
|
#endif /*HAVE_VECTOR_ARITH*/
|
||||||
|
|
||||||
} VipsComposite;
|
} VipsCompositeBase;
|
||||||
|
|
||||||
typedef VipsConversionClass VipsCompositeClass;
|
typedef VipsConversionClass VipsCompositeBaseClass;
|
||||||
|
|
||||||
/* We need C linkage for this.
|
/* We need C linkage for this.
|
||||||
*/
|
*/
|
||||||
extern "C" {
|
extern "C" {
|
||||||
G_DEFINE_TYPE( VipsComposite, vips_composite, VIPS_TYPE_CONVERSION );
|
G_DEFINE_ABSTRACT_TYPE( VipsCompositeBase, vips_composite_base,
|
||||||
|
VIPS_TYPE_CONVERSION );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_composite_base_dispose( GObject *gobject )
|
||||||
|
{
|
||||||
|
VipsCompositeBase *composite = (VipsCompositeBase *) gobject;
|
||||||
|
|
||||||
|
if( composite->in ) {
|
||||||
|
vips_area_unref( (VipsArea *) composite->in );
|
||||||
|
composite->in = NULL;
|
||||||
|
}
|
||||||
|
if( composite->mode ) {
|
||||||
|
vips_area_unref( (VipsArea *) composite->mode );
|
||||||
|
composite->mode = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS( vips_composite_base_parent_class )->dispose( gobject );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For each of the supported interpretations, the maximum value of each band.
|
/* For each of the supported interpretations, the maximum value of each band.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
vips_composite_max_band( VipsComposite *composite, double *max_band )
|
vips_composite_base_max_band( VipsCompositeBase *composite, double *max_band )
|
||||||
{
|
{
|
||||||
double max_alpha;
|
double max_alpha;
|
||||||
int b;
|
int b;
|
||||||
@ -263,7 +283,7 @@ vips_composite_max_band( VipsComposite *composite, double *max_band )
|
|||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void
|
static void
|
||||||
vips_composite_blend( VipsComposite *composite,
|
vips_composite_base_blend( VipsCompositeBase *composite,
|
||||||
VipsBlendMode mode, double * restrict B, T * restrict p )
|
VipsBlendMode mode, double * restrict B, T * restrict p )
|
||||||
{
|
{
|
||||||
const int bands = composite->bands;
|
const int bands = composite->bands;
|
||||||
@ -495,7 +515,7 @@ vips_composite_blend( VipsComposite *composite,
|
|||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void
|
static void
|
||||||
vips_composite_blend3( VipsComposite *composite,
|
vips_composite_base_blend3( VipsCompositeBase *composite,
|
||||||
VipsBlendMode mode, v4f &B, T * restrict p )
|
VipsBlendMode mode, v4f &B, T * restrict p )
|
||||||
{
|
{
|
||||||
v4f A;
|
v4f A;
|
||||||
@ -702,7 +722,7 @@ vips_composite_blend3( VipsComposite *composite,
|
|||||||
*/
|
*/
|
||||||
template <typename T, gint64 min_T, gint64 max_T>
|
template <typename T, gint64 min_T, gint64 max_T>
|
||||||
static void
|
static void
|
||||||
vips_combine_pixels( VipsComposite *composite, VipsPel *q, VipsPel **p )
|
vips_combine_pixels( VipsCompositeBase *composite, VipsPel *q, VipsPel **p )
|
||||||
{
|
{
|
||||||
VipsBlendMode *m = (VipsBlendMode *) composite->mode->area.data;
|
VipsBlendMode *m = (VipsBlendMode *) composite->mode->area.data;
|
||||||
int n = composite->n;
|
int n = composite->n;
|
||||||
@ -724,7 +744,7 @@ vips_combine_pixels( VipsComposite *composite, VipsPel *q, VipsPel **p )
|
|||||||
B[b] *= aB;
|
B[b] *= aB;
|
||||||
|
|
||||||
for( int i = 1; i < n; i++ )
|
for( int i = 1; i < n; i++ )
|
||||||
vips_composite_blend<T>( composite, m[i - 1], B, tp[i] );
|
vips_composite_base_blend<T>( composite, m[i - 1], B, tp[i] );
|
||||||
|
|
||||||
/* Unpremultiply, if necessary.
|
/* Unpremultiply, if necessary.
|
||||||
*/
|
*/
|
||||||
@ -761,7 +781,7 @@ vips_combine_pixels( VipsComposite *composite, VipsPel *q, VipsPel **p )
|
|||||||
*/
|
*/
|
||||||
template <typename T, gint64 min_T, gint64 max_T>
|
template <typename T, gint64 min_T, gint64 max_T>
|
||||||
static void
|
static void
|
||||||
vips_combine_pixels3( VipsComposite *composite, VipsPel *q, VipsPel **p )
|
vips_combine_pixels3( VipsCompositeBase *composite, VipsPel *q, VipsPel **p )
|
||||||
{
|
{
|
||||||
VipsBlendMode *m = (VipsBlendMode *) composite->mode->area.data;
|
VipsBlendMode *m = (VipsBlendMode *) composite->mode->area.data;
|
||||||
int n = composite->n;
|
int n = composite->n;
|
||||||
@ -787,7 +807,7 @@ vips_combine_pixels3( VipsComposite *composite, VipsPel *q, VipsPel **p )
|
|||||||
}
|
}
|
||||||
|
|
||||||
for( int i = 1; i < n; i++ )
|
for( int i = 1; i < n; i++ )
|
||||||
vips_composite_blend3<T>( composite, m[i - 1], B, tp[i] );
|
vips_composite_base_blend3<T>( composite, m[i - 1], B, tp[i] );
|
||||||
|
|
||||||
/* Unpremultiply, if necessary.
|
/* Unpremultiply, if necessary.
|
||||||
*/
|
*/
|
||||||
@ -822,18 +842,18 @@ vips_combine_pixels3( VipsComposite *composite, VipsPel *q, VipsPel **p )
|
|||||||
#endif /*HAVE_VECTOR_ARITH*/
|
#endif /*HAVE_VECTOR_ARITH*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips_composite_gen( VipsRegion *output_region,
|
vips_composite_base_gen( VipsRegion *output_region,
|
||||||
void *seq, void *a, void *b, gboolean *stop )
|
void *seq, void *a, void *b, gboolean *stop )
|
||||||
{
|
{
|
||||||
VipsRegion **input_regions = (VipsRegion **) seq;
|
VipsRegion **input_regions = (VipsRegion **) seq;
|
||||||
VipsComposite *composite = (VipsComposite *) b;
|
VipsCompositeBase *composite = (VipsCompositeBase *) b;
|
||||||
VipsRect *r = &output_region->valid;
|
VipsRect *r = &output_region->valid;
|
||||||
int ps = VIPS_IMAGE_SIZEOF_PEL( output_region->im );
|
int ps = VIPS_IMAGE_SIZEOF_PEL( output_region->im );
|
||||||
|
|
||||||
if( vips_reorder_prepare_many( output_region->im, input_regions, r ) )
|
if( vips_reorder_prepare_many( output_region->im, input_regions, r ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
VIPS_GATE_START( "vips_composite_gen: work" );
|
VIPS_GATE_START( "vips_composite_base_gen: work" );
|
||||||
|
|
||||||
for( int y = 0; y < r->height; y++ ) {
|
for( int y = 0; y < r->height; y++ ) {
|
||||||
VipsPel *p[MAX_INPUT_IMAGES];
|
VipsPel *p[MAX_INPUT_IMAGES];
|
||||||
@ -927,17 +947,17 @@ vips_composite_gen( VipsRegion *output_region,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VIPS_GATE_STOP( "vips_composite_gen: work" );
|
VIPS_GATE_STOP( "vips_composite_base_gen: work" );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips_composite_build( VipsObject *object )
|
vips_composite_base_build( VipsObject *object )
|
||||||
{
|
{
|
||||||
VipsObjectClass *klass = VIPS_OBJECT_GET_CLASS( object );
|
VipsObjectClass *klass = VIPS_OBJECT_GET_CLASS( object );
|
||||||
VipsConversion *conversion = VIPS_CONVERSION( object );
|
VipsConversion *conversion = VIPS_CONVERSION( object );
|
||||||
VipsComposite *composite = (VipsComposite *) object;
|
VipsCompositeBase *composite = (VipsCompositeBase *) object;
|
||||||
|
|
||||||
VipsImage **in;
|
VipsImage **in;
|
||||||
VipsImage **decode;
|
VipsImage **decode;
|
||||||
@ -946,7 +966,8 @@ vips_composite_build( VipsObject *object )
|
|||||||
VipsImage **size;
|
VipsImage **size;
|
||||||
VipsBlendMode *mode;
|
VipsBlendMode *mode;
|
||||||
|
|
||||||
if( VIPS_OBJECT_CLASS( vips_composite_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_composite_base_parent_class )->
|
||||||
|
build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
composite->n = composite->in->area.n;
|
composite->n = composite->in->area.n;
|
||||||
@ -1064,7 +1085,7 @@ vips_composite_build( VipsObject *object )
|
|||||||
|
|
||||||
/* Set the max for each band now we know bands and compositing space.
|
/* Set the max for each band now we know bands and compositing space.
|
||||||
*/
|
*/
|
||||||
if( vips_composite_max_band( composite, composite->max_band ) ) {
|
if( vips_composite_base_max_band( composite, composite->max_band ) ) {
|
||||||
vips_error( klass->nickname,
|
vips_error( klass->nickname,
|
||||||
"%s", _( "unsupported compositing space" ) );
|
"%s", _( "unsupported compositing space" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -1093,13 +1114,67 @@ vips_composite_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_generate( conversion->out,
|
if( vips_image_generate( conversion->out,
|
||||||
vips_start_many, vips_composite_gen, vips_stop_many,
|
vips_start_many, vips_composite_base_gen, vips_stop_many,
|
||||||
in, composite ) )
|
in, composite ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_composite_base_class_init( VipsCompositeBaseClass *klass )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
|
||||||
|
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( klass );
|
||||||
|
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( klass );
|
||||||
|
|
||||||
|
VIPS_DEBUG_MSG( "vips_composite_base_class_init\n" );
|
||||||
|
|
||||||
|
gobject_class->dispose = vips_composite_base_dispose;
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
vobject_class->nickname = "composite_base";
|
||||||
|
vobject_class->description = _( "blend images together" );
|
||||||
|
vobject_class->build = vips_composite_base_build;
|
||||||
|
|
||||||
|
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||||
|
|
||||||
|
VIPS_ARG_ENUM( klass, "compositing_space", 10,
|
||||||
|
_( "Compositing space" ),
|
||||||
|
_( "Composite images in this colour space" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsCompositeBase, compositing_space ),
|
||||||
|
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_sRGB );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( klass, "premultiplied", 11,
|
||||||
|
_( "Premultiplied" ),
|
||||||
|
_( "Images have premultiplied alpha" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsCompositeBase, premultiplied ),
|
||||||
|
FALSE );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_composite_base_init( VipsCompositeBase *composite )
|
||||||
|
{
|
||||||
|
composite->compositing_space = VIPS_INTERPRETATION_sRGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsComposite {
|
||||||
|
VipsCompositeBase parent_instance;
|
||||||
|
|
||||||
|
} VipsComposite;
|
||||||
|
|
||||||
|
typedef VipsCompositeBaseClass VipsCompositeClass;
|
||||||
|
|
||||||
|
/* We need C linkage for this.
|
||||||
|
*/
|
||||||
|
extern "C" {
|
||||||
|
G_DEFINE_TYPE( VipsComposite, vips_composite, vips_composite_base_get_type() );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_composite_class_init( VipsCompositeClass *klass )
|
vips_composite_class_init( VipsCompositeClass *klass )
|
||||||
{
|
{
|
||||||
@ -1115,7 +1190,7 @@ vips_composite_class_init( VipsCompositeClass *klass )
|
|||||||
vobject_class->nickname = "composite";
|
vobject_class->nickname = "composite";
|
||||||
vobject_class->description =
|
vobject_class->description =
|
||||||
_( "blend an array of images with an array of blend modes" );
|
_( "blend an array of images with an array of blend modes" );
|
||||||
vobject_class->build = vips_composite_build;
|
vobject_class->build = vips_composite_base_build;
|
||||||
|
|
||||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||||
|
|
||||||
@ -1123,36 +1198,21 @@ vips_composite_class_init( VipsCompositeClass *klass )
|
|||||||
_( "Inputs" ),
|
_( "Inputs" ),
|
||||||
_( "Array of input images" ),
|
_( "Array of input images" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsComposite, in ),
|
G_STRUCT_OFFSET( VipsCompositeBase, in ),
|
||||||
VIPS_TYPE_ARRAY_IMAGE );
|
VIPS_TYPE_ARRAY_IMAGE );
|
||||||
|
|
||||||
VIPS_ARG_BOXED( klass, "mode", 3,
|
VIPS_ARG_BOXED( klass, "mode", 3,
|
||||||
_( "Blend modes" ),
|
_( "Blend modes" ),
|
||||||
_( "Array of VipsBlendMode to join with" ),
|
_( "Array of VipsBlendMode to join with" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsComposite, mode ),
|
G_STRUCT_OFFSET( VipsCompositeBase, mode ),
|
||||||
VIPS_TYPE_ARRAY_INT );
|
VIPS_TYPE_ARRAY_INT );
|
||||||
|
|
||||||
VIPS_ARG_ENUM( klass, "compositing_space", 10,
|
|
||||||
_( "Compositing space" ),
|
|
||||||
_( "Composite images in this colour space" ),
|
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
|
||||||
G_STRUCT_OFFSET( VipsComposite, compositing_space ),
|
|
||||||
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_sRGB );
|
|
||||||
|
|
||||||
VIPS_ARG_BOOL( klass, "premultiplied", 11,
|
|
||||||
_( "Premultiplied" ),
|
|
||||||
_( "Images have premultiplied alpha" ),
|
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
|
||||||
G_STRUCT_OFFSET( VipsComposite, premultiplied ),
|
|
||||||
FALSE );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_composite_init( VipsComposite *composite )
|
vips_composite_init( VipsComposite *composite )
|
||||||
{
|
{
|
||||||
composite->compositing_space = VIPS_INTERPRETATION_sRGB;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1232,6 +1292,94 @@ vips_composite( VipsImage **in, VipsImage **out, int n, int *mode, ... )
|
|||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsComposite2 {
|
||||||
|
VipsCompositeBase parent_instance;
|
||||||
|
|
||||||
|
VipsImage *base;
|
||||||
|
VipsImage *overlay;
|
||||||
|
VipsBlendMode mode;
|
||||||
|
|
||||||
|
} VipsComposite2;
|
||||||
|
|
||||||
|
typedef VipsCompositeBaseClass VipsComposite2Class;
|
||||||
|
|
||||||
|
/* We need C linkage for this.
|
||||||
|
*/
|
||||||
|
extern "C" {
|
||||||
|
G_DEFINE_TYPE( VipsComposite2, vips_composite2, vips_composite_base_get_type() );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_composite2_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsCompositeBase *base = (VipsCompositeBase *) object;
|
||||||
|
VipsComposite2 *composite2 = (VipsComposite2 *) object;
|
||||||
|
|
||||||
|
if( composite2->overlay &&
|
||||||
|
composite2->base ) {
|
||||||
|
VipsImage *in[3];
|
||||||
|
int mode[1];
|
||||||
|
|
||||||
|
in[0] = composite2->base;
|
||||||
|
in[1] = composite2->overlay;
|
||||||
|
in[2] = NULL;
|
||||||
|
base->in = vips_array_image_new( in, 2 );
|
||||||
|
|
||||||
|
mode[0] = (int) composite2->mode;
|
||||||
|
base->mode = vips_array_int_new( mode, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_composite2_parent_class )->build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_composite2_class_init( VipsCompositeClass *klass )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
|
||||||
|
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( klass );
|
||||||
|
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( klass );
|
||||||
|
|
||||||
|
VIPS_DEBUG_MSG( "vips_composite_class_init\n" );
|
||||||
|
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
vobject_class->nickname = "composite2";
|
||||||
|
vobject_class->description =
|
||||||
|
_( "blend a pair of images with a blend mode" );
|
||||||
|
vobject_class->build = vips_composite2_build;
|
||||||
|
|
||||||
|
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
||||||
|
|
||||||
|
VIPS_ARG_IMAGE( klass, "base", 0,
|
||||||
|
_( "Base" ),
|
||||||
|
_( "Base image" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsComposite2, base ) );
|
||||||
|
|
||||||
|
VIPS_ARG_IMAGE( klass, "overlay", 1,
|
||||||
|
_( "Overlay" ),
|
||||||
|
_( "Overlay image" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsComposite2, overlay ) );
|
||||||
|
|
||||||
|
VIPS_ARG_ENUM( klass, "mode", 3,
|
||||||
|
_( "Blend mode" ),
|
||||||
|
_( "VipsBlendMode to join with" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsComposite2, mode ),
|
||||||
|
VIPS_TYPE_BLEND_MODE, VIPS_BLEND_MODE_OVER );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_composite2_init( VipsComposite2 *composite2 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_composite2: (method)
|
* vips_composite2: (method)
|
||||||
* @base: first input image
|
* @base: first input image
|
||||||
@ -1240,7 +1388,7 @@ vips_composite( VipsImage **in, VipsImage **out, int n, int *mode, ... )
|
|||||||
* @mode: composite with this blend mode
|
* @mode: composite with this blend mode
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
*
|
*
|
||||||
* Composite @overlay on top of @base with @mode. See vips_composite().
|
* Composite @overlay on top of @base with @mode. See vips_composite_base().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
@ -1250,16 +1398,11 @@ vips_composite2( VipsImage *base, VipsImage *overlay, VipsImage **out,
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
VipsImage *imagev[2];
|
|
||||||
int modev[1];
|
|
||||||
|
|
||||||
imagev[0] = base;
|
|
||||||
imagev[1] = overlay;
|
|
||||||
modev[0] = mode;
|
|
||||||
|
|
||||||
va_start( ap, mode );
|
va_start( ap, mode );
|
||||||
result = vips_compositev( imagev, out, 2, modev, ap );
|
result = vips_call_split( "composite2", ap, base, overlay, out, mode );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +291,7 @@ vips_conversion_operation_init( void )
|
|||||||
extern GType vips_falsecolour_get_type( void );
|
extern GType vips_falsecolour_get_type( void );
|
||||||
extern GType vips_gamma_get_type( void );
|
extern GType vips_gamma_get_type( void );
|
||||||
extern GType vips_composite_get_type( void );
|
extern GType vips_composite_get_type( void );
|
||||||
|
extern GType vips_composite2_get_type( void );
|
||||||
|
|
||||||
vips_copy_get_type();
|
vips_copy_get_type();
|
||||||
vips_tile_cache_get_type();
|
vips_tile_cache_get_type();
|
||||||
@ -340,4 +341,5 @@ vips_conversion_operation_init( void )
|
|||||||
vips_falsecolour_get_type();
|
vips_falsecolour_get_type();
|
||||||
vips_gamma_get_type();
|
vips_gamma_get_type();
|
||||||
vips_composite_get_type();
|
vips_composite_get_type();
|
||||||
|
vips_composite2_get_type();
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ int vips_unpremultiply( VipsImage *in, VipsImage **out, ... )
|
|||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_composite( VipsImage **in, VipsImage **out, int n, int *mode, ... )
|
int vips_composite( VipsImage **in, VipsImage **out, int n, int *mode, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_composite2( VipsImage *in1, VipsImage *in2, VipsImage **out,
|
int vips_composite2( VipsImage *base, VipsImage *overlay, VipsImage **out,
|
||||||
VipsBlendMode mode1, ... )
|
VipsBlendMode mode1, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user