now compiles with new add.c
compiles, but not tested
This commit is contained in:
parent
370641d25b
commit
ce03da8c71
@ -27,6 +27,7 @@ libarithmetic_la_SOURCES = \
|
|||||||
math.c \
|
math.c \
|
||||||
arithmetic.c \
|
arithmetic.c \
|
||||||
binary.c \
|
binary.c \
|
||||||
|
add.c \
|
||||||
power.c \
|
power.c \
|
||||||
round.c
|
round.c
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /*HAVE_CONFIG_H*/
|
#endif /*HAVE_CONFIG_H*/
|
||||||
#include <vips8/intl.h>
|
#include <vips/intl.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -73,33 +73,33 @@ typedef VipsBinaryClass VipsAddClass;
|
|||||||
G_DEFINE_TYPE( VipsAdd, vips_add, VIPS_TYPE_BINARY );
|
G_DEFINE_TYPE( VipsAdd, vips_add, VIPS_TYPE_BINARY );
|
||||||
|
|
||||||
#define LOOP( IN, OUT ) { \
|
#define LOOP( IN, OUT ) { \
|
||||||
IN *p1 = (IN *) in[0]; \
|
IN *p1 = (IN *) left; \
|
||||||
IN *p2 = (IN *) in[1]; \
|
IN *p2 = (IN *) right; \
|
||||||
OUT *q = (OUT *) out; \
|
OUT *q = (OUT *) out; \
|
||||||
\
|
\
|
||||||
for( x = 0; x < sz; x++ ) \
|
for( x = 0; x < sz; x++ ) \
|
||||||
q[x] = p1[x] + p2[x]; \
|
q[x] = p1[x] + p2[x]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static VipsVector *add_vectors[VIPS_FORMAT_LAST] = { NULL };
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
add_buffer( VipsBinary *binary, PEL *out, PEL *left, PEL *right, int width )
|
||||||
{
|
{
|
||||||
|
VipsArithmeticClass *class = VIPS_ARITHMETIC_GET_CLASS( binary );
|
||||||
|
VipsImage *im = binary->left_processed;
|
||||||
|
|
||||||
/* Complex just doubles the size.
|
/* Complex just doubles the size.
|
||||||
*/
|
*/
|
||||||
const int sz = width * im->Bands *
|
const int sz = width * im->Bands *
|
||||||
(vips_bandfmt_iscomplex( im->BandFmt ) ? 2 : 1);
|
(vips_band_format_iscomplex( im->BandFmt ) ? 2 : 1);
|
||||||
|
|
||||||
if( vips_vector_get_enabled() &&
|
VipsVector *v;
|
||||||
add_vectors[im->BandFmt] ) {
|
|
||||||
VipsVector *vector = add_vectors[im->BandFmt];
|
|
||||||
|
|
||||||
|
if( (v = vips_arithmetic_get_vector( class, im->BandFmt )) ) {
|
||||||
VipsExecutor ex;
|
VipsExecutor ex;
|
||||||
|
|
||||||
vips_executor_set_program( &ex, vector, sz );
|
vips_executor_set_program( &ex, v, sz );
|
||||||
vips_executor_set_array( &ex, vector->s[0], in[0] );
|
vips_executor_set_array( &ex, v->s[0], left );
|
||||||
vips_executor_set_array( &ex, vector->s[1], in[1] );
|
vips_executor_set_array( &ex, v->s[1], right );
|
||||||
vips_executor_set_destination( &ex, out );
|
vips_executor_set_destination( &ex, out );
|
||||||
|
|
||||||
vips_executor_run( &ex );
|
vips_executor_run( &ex );
|
||||||
@ -151,47 +151,6 @@ add_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
|||||||
#define D IM_BANDFMT_DOUBLE
|
#define D IM_BANDFMT_DOUBLE
|
||||||
#define DX IM_BANDFMT_DPCOMPLEX
|
#define DX IM_BANDFMT_DPCOMPLEX
|
||||||
|
|
||||||
VipsVector *
|
|
||||||
im__init_program( VipsVector *vectors[IM_BANDFMT_LAST],
|
|
||||||
VipsBandFmt format_table[IM_BANDFMT_LAST], VipsBandFmt fmt )
|
|
||||||
{
|
|
||||||
int isize = im__sizeof_bandfmt[fmt];
|
|
||||||
int osize = im__sizeof_bandfmt[format_table[fmt]];
|
|
||||||
|
|
||||||
VipsVector *v;
|
|
||||||
|
|
||||||
v = vips_vector_new( "binary arith", osize );
|
|
||||||
|
|
||||||
vips_vector_source_name( v, "s1", isize );
|
|
||||||
vips_vector_source_name( v, "s2", isize );
|
|
||||||
vips_vector_temporary( v, "t1", osize );
|
|
||||||
vips_vector_temporary( v, "t2", osize );
|
|
||||||
|
|
||||||
vectors[fmt] = v;
|
|
||||||
|
|
||||||
return( v );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
im__compile_programs( VipsVector *vectors[IM_BANDFMT_LAST] )
|
|
||||||
{
|
|
||||||
int fmt;
|
|
||||||
|
|
||||||
for( fmt = 0; fmt < IM_BANDFMT_LAST; fmt++ ) {
|
|
||||||
if( vectors[fmt] &&
|
|
||||||
!vips_vector_compile( vectors[fmt] ) )
|
|
||||||
IM_FREEF( vips_vector_free, vectors[fmt] );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "im__compile_programs: " );
|
|
||||||
for( fmt = 0; fmt < IM_BANDFMT_LAST; fmt++ )
|
|
||||||
if( vectors[fmt] )
|
|
||||||
printf( "%s ", im_BandFmt2char( fmt ) );
|
|
||||||
printf( "\n" );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Type promotion for addition. Sign and value preserving. Make sure these
|
/* Type promotion for addition. Sign and value preserving. Make sure these
|
||||||
* match the case statement in add_buffer() above.
|
* match the case statement in add_buffer() above.
|
||||||
*/
|
*/
|
||||||
@ -201,32 +160,30 @@ static int bandfmt_add[10] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_programs( void )
|
vips_add_class_init( VipsAddClass *class )
|
||||||
{
|
{
|
||||||
static gboolean done = FALSE;
|
VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class );
|
||||||
|
VipsBinaryClass *bclass = VIPS_BINARY_CLASS( class );
|
||||||
VipsVector *v;
|
VipsVector *v;
|
||||||
|
|
||||||
if( done )
|
vips_arithmetic_set_format_table( aclass, bandfmt_add );
|
||||||
return;
|
|
||||||
done = TRUE;
|
|
||||||
|
|
||||||
v = im__init_program( add_vectors, bandfmt_add, IM_BANDFMT_UCHAR );
|
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_UCHAR );
|
||||||
vips_vector_asm2( v, "convubw", "t1", "s1" );
|
vips_vector_asm2( v, "convubw", "t1", "s1" );
|
||||||
vips_vector_asm2( v, "convubw", "t2", "s2" );
|
vips_vector_asm2( v, "convubw", "t2", "s2" );
|
||||||
vips_vector_asm3( v, "addw", "d1", "t1", "t2" );
|
vips_vector_asm3( v, "addw", "d1", "t1", "t2" );
|
||||||
|
|
||||||
v = im__init_program( add_vectors, bandfmt_add, IM_BANDFMT_CHAR );
|
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_CHAR );
|
||||||
vips_vector_asm2( v, "convsbw", "t1", "s1" );
|
vips_vector_asm2( v, "convsbw", "t1", "s1" );
|
||||||
vips_vector_asm2( v, "convsbw", "t2", "s2" );
|
vips_vector_asm2( v, "convsbw", "t2", "s2" );
|
||||||
vips_vector_asm3( v, "addw", "d1", "t1", "t2" );
|
vips_vector_asm3( v, "addw", "d1", "t1", "t2" );
|
||||||
|
|
||||||
v = im__init_program( add_vectors, bandfmt_add, IM_BANDFMT_USHORT );
|
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_USHORT );
|
||||||
vips_vector_asm2( v, "convuwl", "t1", "s1" );
|
vips_vector_asm2( v, "convuwl", "t1", "s1" );
|
||||||
vips_vector_asm2( v, "convuwl", "t2", "s2" );
|
vips_vector_asm2( v, "convuwl", "t2", "s2" );
|
||||||
vips_vector_asm3( v, "addl", "d1", "t1", "t2" );
|
vips_vector_asm3( v, "addl", "d1", "t1", "t2" );
|
||||||
|
|
||||||
v = im__init_program( add_vectors, bandfmt_add, IM_BANDFMT_SHORT );
|
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_SHORT );
|
||||||
vips_vector_asm2( v, "convswl", "t1", "s1" );
|
vips_vector_asm2( v, "convswl", "t1", "s1" );
|
||||||
vips_vector_asm2( v, "convswl", "t2", "s2" );
|
vips_vector_asm2( v, "convswl", "t2", "s2" );
|
||||||
vips_vector_asm3( v, "addl", "d1", "t1", "t2" );
|
vips_vector_asm3( v, "addl", "d1", "t1", "t2" );
|
||||||
@ -237,14 +194,20 @@ build_programs( void )
|
|||||||
|
|
||||||
float/double/complex are not handled well
|
float/double/complex are not handled well
|
||||||
|
|
||||||
v = im__init_program( add_vectors, IM_BANDFMT_UINT );
|
v = vips_arithmetic_get_vector( aclass, VIPS_FORMAT_UINT );
|
||||||
vips_vector_asm3( v, "addl", "d1", "s1", "s2" );
|
vips_vector_asm3( v, "addl", "d1", "s1", "s2" );
|
||||||
|
|
||||||
v = im__init_program( add_vectors, IM_BANDFMT_INT );
|
v = vips_arithmetic_get_vector( aclass, VIPS_FORMAT_INT );
|
||||||
vips_vector_asm3( v, "addl", "d1", "s1", "s2" );
|
vips_vector_asm3( v, "addl", "d1", "s1", "s2" );
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
im__compile_programs( add_vectors );
|
vips_arithmetic_compile( aclass );
|
||||||
|
|
||||||
|
bclass->process_line = add_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_add_init( VipsAdd *add )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /*HAVE_CONFIG_H*/
|
#endif /*HAVE_CONFIG_H*/
|
||||||
#include <vips8/intl.h>
|
#include <vips/intl.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -69,8 +69,6 @@ G_DEFINE_ABSTRACT_TYPE( VipsArithmetic, vips_arithmetic, VIPS_TYPE_OPERATION );
|
|||||||
static int
|
static int
|
||||||
vips_arithmetic_build( VipsObject *object )
|
vips_arithmetic_build( VipsObject *object )
|
||||||
{
|
{
|
||||||
VipsArithmetic *arithmetic = VIPS_ARITHMETIC (object);
|
|
||||||
|
|
||||||
if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -110,6 +108,85 @@ vips_arithmetic_init( VipsArithmetic *arithmetic )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vips_arithmetic_set_format_table( VipsArithmeticClass *class,
|
||||||
|
VipsBandFormat *format_table )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_assert( !class->format_table );
|
||||||
|
|
||||||
|
class->format_table = format_table;
|
||||||
|
|
||||||
|
for( i = 0; i < VIPS_FORMAT_LAST; i++ ) {
|
||||||
|
int isize = vips_format_sizeof( i );
|
||||||
|
int osize = vips_format_sizeof( (int) format_table[i] );
|
||||||
|
|
||||||
|
VipsVector *v;
|
||||||
|
|
||||||
|
v = vips_vector_new( "arithmetic", osize );
|
||||||
|
|
||||||
|
vips_vector_source_name( v, "s1", isize );
|
||||||
|
vips_vector_source_name( v, "s2", isize );
|
||||||
|
vips_vector_temporary( v, "t1", osize );
|
||||||
|
vips_vector_temporary( v, "t2", osize );
|
||||||
|
|
||||||
|
class->vectors[i] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the stub for this program ... use _get_vector() to get the compiled
|
||||||
|
* code.
|
||||||
|
*/
|
||||||
|
VipsVector *
|
||||||
|
vips_arithmetic_get_program( VipsArithmeticClass *class, VipsBandFormat fmt )
|
||||||
|
{
|
||||||
|
g_assert( (int) fmt >= 0 && (int) fmt < VIPS_FORMAT_LAST );
|
||||||
|
g_assert( !class->vector_program[fmt] );
|
||||||
|
|
||||||
|
class->vector_program[fmt] = TRUE;
|
||||||
|
|
||||||
|
return( class->vectors[fmt] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the compiled code for this type, if available.
|
||||||
|
*/
|
||||||
|
VipsVector *
|
||||||
|
vips_arithmetic_get_vector( VipsArithmeticClass *class, VipsBandFormat fmt )
|
||||||
|
{
|
||||||
|
g_assert( fmt >= 0 && fmt < VIPS_FORMAT_LAST );
|
||||||
|
|
||||||
|
if( !vips_vector_get_enabled() ||
|
||||||
|
!class->vector_program[fmt] )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
return( class->vectors[fmt] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vips_arithmetic_compile( VipsArithmeticClass *class )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_assert( class->format_table );
|
||||||
|
|
||||||
|
for( i = 0; i < VIPS_FORMAT_LAST; i++ )
|
||||||
|
if( class->vector_program[i] &&
|
||||||
|
!vips_vector_compile( class->vectors[i] ) )
|
||||||
|
/* If compilation fails, turn off the vector for this
|
||||||
|
* type.
|
||||||
|
*/
|
||||||
|
class->vector_program[i] = FALSE;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "vips_arithmetic_compile: " );
|
||||||
|
for( i = 0; i < IM_BANDFMT_LAST; i++ )
|
||||||
|
if( class->vector_program[i] )
|
||||||
|
printf( "%s ", VIPS_ENUM_NICK( VIPS_TYPE_FORMAT, i ) );
|
||||||
|
printf( "\n" );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
}
|
||||||
|
|
||||||
/* Called from iofuncs to init all operations in this dir. Use a plugin system
|
/* Called from iofuncs to init all operations in this dir. Use a plugin system
|
||||||
* instead?
|
* instead?
|
||||||
*/
|
*/
|
||||||
@ -120,3 +197,4 @@ vips_arithmetic_operation_init( void )
|
|||||||
|
|
||||||
vips_add_get_type();
|
vips_add_get_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
|
||||||
|
#include <vips/vector.h>
|
||||||
|
|
||||||
#define VIPS_TYPE_ARITHMETIC (vips_arithmetic_get_type())
|
#define VIPS_TYPE_ARITHMETIC (vips_arithmetic_get_type())
|
||||||
#define VIPS_ARITHMETIC( obj ) \
|
#define VIPS_ARITHMETIC( obj ) \
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
||||||
@ -56,19 +58,35 @@ typedef struct _VipsArithmetic {
|
|||||||
*/
|
*/
|
||||||
VipsImage *output;
|
VipsImage *output;
|
||||||
|
|
||||||
/* For each input format, what output format. Used for arithmetic
|
|
||||||
* too, since we cast inputs to match.
|
|
||||||
*/
|
|
||||||
VipsFormat *cast_table;
|
|
||||||
} VipsArithmetic;
|
} VipsArithmetic;
|
||||||
|
|
||||||
typedef struct _VipsArithmeticClass {
|
typedef struct _VipsArithmeticClass {
|
||||||
VipsOperationClass parent_class;
|
VipsOperationClass parent_class;
|
||||||
|
|
||||||
|
/* For each input format, what output format. Used for arithmetic
|
||||||
|
* too, since we cast inputs to match.
|
||||||
|
*/
|
||||||
|
VipsBandFormat *format_table;
|
||||||
|
|
||||||
|
/* A vector program for each input type.
|
||||||
|
*/
|
||||||
|
VipsVector *vectors[VIPS_FORMAT_LAST];
|
||||||
|
|
||||||
|
/* ... and if we've set a program for this format.
|
||||||
|
*/
|
||||||
|
gboolean vector_program[VIPS_FORMAT_LAST];
|
||||||
} VipsArithmeticClass;
|
} VipsArithmeticClass;
|
||||||
|
|
||||||
GType vips_arithmetic_get_type( void );
|
GType vips_arithmetic_get_type( void );
|
||||||
|
|
||||||
|
void vips_arithmetic_set_format_table( VipsArithmeticClass *klass,
|
||||||
|
VipsBandFormat *format_table );
|
||||||
|
VipsVector *vips_arithmetic_get_vector( VipsArithmeticClass *klass,
|
||||||
|
VipsBandFormat fmt );
|
||||||
|
void vips_arithmetic_compile( VipsArithmeticClass *klass );
|
||||||
|
VipsVector *vips_arithmetic_get_program( VipsArithmeticClass *klass,
|
||||||
|
VipsBandFormat fmt );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /*HAVE_CONFIG_H*/
|
#endif /*HAVE_CONFIG_H*/
|
||||||
#include <vips8/intl.h>
|
#include <vips/intl.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -75,7 +75,7 @@ G_DEFINE_ABSTRACT_TYPE( VipsBinary, vips_binary, VIPS_TYPE_ARITHMETIC );
|
|||||||
/* For two integer types, the "largest", ie. one which can represent the
|
/* For two integer types, the "largest", ie. one which can represent the
|
||||||
* full range of both.
|
* full range of both.
|
||||||
*/
|
*/
|
||||||
static VipsFormat format_largest[6][6] = {
|
static VipsBandFormat format_largest[6][6] = {
|
||||||
/* UC C US S UI I */
|
/* UC C US S UI I */
|
||||||
/* UC */ { UC, S, US, S, UI, I },
|
/* UC */ { UC, S, US, S, UI, I },
|
||||||
/* C */ { S, C, I, S, I, I },
|
/* C */ { S, C, I, S, I, I },
|
||||||
@ -87,11 +87,11 @@ static VipsFormat format_largest[6][6] = {
|
|||||||
|
|
||||||
/* For two formats, find one which can represent the full range of both.
|
/* For two formats, find one which can represent the full range of both.
|
||||||
*/
|
*/
|
||||||
static VipsFormat
|
static VipsBandFormat
|
||||||
vips_format_common( VipsFormat a, VipsFormat b )
|
vips_format_common( VipsBandFormat a, VipsBandFormat b )
|
||||||
{
|
{
|
||||||
if( vips_format_iscomplex( a ) ||
|
if( vips_band_format_iscomplex( a ) ||
|
||||||
vips_format_iscomplex( b ) ) {
|
vips_band_format_iscomplex( b ) ) {
|
||||||
if( a == VIPS_FORMAT_DPCOMPLEX ||
|
if( a == VIPS_FORMAT_DPCOMPLEX ||
|
||||||
b == VIPS_FORMAT_DPCOMPLEX )
|
b == VIPS_FORMAT_DPCOMPLEX )
|
||||||
return( VIPS_FORMAT_DPCOMPLEX );
|
return( VIPS_FORMAT_DPCOMPLEX );
|
||||||
@ -99,8 +99,8 @@ vips_format_common( VipsFormat a, VipsFormat b )
|
|||||||
return( VIPS_FORMAT_COMPLEX );
|
return( VIPS_FORMAT_COMPLEX );
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( vips_format_isfloat( a ) ||
|
else if( vips_band_format_isfloat( a ) ||
|
||||||
vips_format_isfloat( b ) ) {
|
vips_band_format_isfloat( b ) ) {
|
||||||
if( a == VIPS_FORMAT_DOUBLE ||
|
if( a == VIPS_FORMAT_DOUBLE ||
|
||||||
b == VIPS_FORMAT_DOUBLE )
|
b == VIPS_FORMAT_DOUBLE )
|
||||||
return( VIPS_FORMAT_DOUBLE );
|
return( VIPS_FORMAT_DOUBLE );
|
||||||
@ -115,13 +115,13 @@ int
|
|||||||
vips__formatalike_vec( VipsImage **in, VipsImage **out, int n )
|
vips__formatalike_vec( VipsImage **in, VipsImage **out, int n )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
VipsFormat format;
|
VipsBandFormat format;
|
||||||
|
|
||||||
g_assert( n >= 1 );
|
g_assert( n >= 1 );
|
||||||
|
|
||||||
format = in[0]->BandFmt;
|
format = in[0]->BandFmt;
|
||||||
for( i = 1; i < n; i++ )
|
for( i = 1; i < n; i++ )
|
||||||
fmt = vips_format_common( format, in[i]->BandFmt );
|
format = vips_format_common( format, in[i]->BandFmt );
|
||||||
|
|
||||||
for( i = 0; i < n; i++ )
|
for( i = 0; i < n; i++ )
|
||||||
if( im_clip2fmt( in[i], out[i], format ) )
|
if( im_clip2fmt( in[i], out[i], format ) )
|
||||||
@ -219,6 +219,7 @@ vips_binary_process_region( VipsRegion *or, void *seq, void *a, void *b )
|
|||||||
{
|
{
|
||||||
VipsRegion **ir = (VipsRegion **) seq;
|
VipsRegion **ir = (VipsRegion **) seq;
|
||||||
VipsBinary *binary = VIPS_BINARY( b );
|
VipsBinary *binary = VIPS_BINARY( b );
|
||||||
|
VipsBinaryClass *class = VIPS_BINARY_GET_CLASS( binary );
|
||||||
|
|
||||||
PEL *p[MAX_INPUT_IMAGES], *q;
|
PEL *p[MAX_INPUT_IMAGES], *q;
|
||||||
int i, y;
|
int i, y;
|
||||||
@ -237,7 +238,7 @@ vips_binary_process_region( VipsRegion *or, void *seq, void *a, void *b )
|
|||||||
for( y = 0; y < or->valid.height; y++ ) {
|
for( y = 0; y < or->valid.height; y++ ) {
|
||||||
/* Bizarre double-cast stops a bogus gcc 4.1 compiler warning.
|
/* Bizarre double-cast stops a bogus gcc 4.1 compiler warning.
|
||||||
*/
|
*/
|
||||||
binary->process_line( binary, q, p[0], p[1], or->valid.width );
|
class->process_line( binary, q, p[0], p[1], or->valid.width );
|
||||||
|
|
||||||
for( i = 0; ir[i]; i++ )
|
for( i = 0; ir[i]; i++ )
|
||||||
p[i] += VIPS_REGION_LSKIP( ir[i] );
|
p[i] += VIPS_REGION_LSKIP( ir[i] );
|
||||||
@ -253,6 +254,7 @@ vips_binary_build( VipsObject *object )
|
|||||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||||
const char *domain = class->description;
|
const char *domain = class->description;
|
||||||
VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object );
|
VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object );
|
||||||
|
VipsArithmeticClass *aclass = VIPS_ARITHMETIC_GET_CLASS( arithmetic );
|
||||||
VipsBinary *binary = VIPS_BINARY( object );
|
VipsBinary *binary = VIPS_BINARY( object );
|
||||||
|
|
||||||
VipsImage *t[5];
|
VipsImage *t[5];
|
||||||
@ -284,15 +286,15 @@ vips_binary_build( VipsObject *object )
|
|||||||
/* Hint demand style. Being a buffer processor, we are happiest with
|
/* Hint demand style. Being a buffer processor, we are happiest with
|
||||||
* thin strips.
|
* thin strips.
|
||||||
*/
|
*/
|
||||||
if( vips_demand_hint_array( binary->output,
|
if( vips_demand_hint_array( arithmetic->output,
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, t + 2 ) ||
|
VIPS_DEMAND_STYLE_THINSTRIP, t + 2 ) ||
|
||||||
vips_image_copy_fields_array( binary->output, t + 2 ) )
|
vips_image_copy_fields_array( arithmetic->output, t + 2 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
binary->output->Bands = t[2]->Bands;
|
arithmetic->output->Bands = t[2]->Bands;
|
||||||
binary->output->BandFmt = arithmetic->cast_table[t[2]->BandFmt];
|
arithmetic->output->BandFmt = aclass->format_table[t[2]->BandFmt];
|
||||||
|
|
||||||
if( vips_image_generate( binary->output,
|
if( vips_image_generate( arithmetic->output,
|
||||||
vips_start_many, vips_binary_process_region,
|
vips_start_many, vips_binary_process_region,
|
||||||
vips_stop_many,
|
vips_stop_many,
|
||||||
t + 2, binary ) )
|
t + 2, binary ) )
|
||||||
|
@ -46,8 +46,9 @@ extern "C" {
|
|||||||
#define VIPS_BINARY_GET_CLASS( obj ) \
|
#define VIPS_BINARY_GET_CLASS( obj ) \
|
||||||
(G_TYPE_INSTANCE_GET_CLASS( (obj), VIPS_TYPE_BINARY, VipsBinaryClass ))
|
(G_TYPE_INSTANCE_GET_CLASS( (obj), VIPS_TYPE_BINARY, VipsBinaryClass ))
|
||||||
|
|
||||||
typedef void (*VipsBinaryProcessFn)( VipsBinary *binary,
|
struct _VipsBinary;
|
||||||
void *out, void *left, void *right, int width );
|
typedef void (*VipsBinaryProcessFn)( struct _VipsBinary *binary,
|
||||||
|
PEL *out, PEL *left, PEL *right, int width );
|
||||||
|
|
||||||
typedef struct _VipsBinary {
|
typedef struct _VipsBinary {
|
||||||
VipsArithmetic parent_instance;
|
VipsArithmetic parent_instance;
|
||||||
@ -66,9 +67,8 @@ typedef struct _VipsBinary {
|
|||||||
VipsImage *left_processed;
|
VipsImage *left_processed;
|
||||||
VipsImage *right_processed;
|
VipsImage *right_processed;
|
||||||
|
|
||||||
/* The line processor, plus some client data.
|
/* Some client data for the line processor, if it wants it.
|
||||||
*/
|
*/
|
||||||
VipsBinaryProcessFn process_line;
|
|
||||||
void *a;
|
void *a;
|
||||||
void *b;
|
void *b;
|
||||||
} VipsBinary;
|
} VipsBinary;
|
||||||
@ -76,6 +76,10 @@ typedef struct _VipsBinary {
|
|||||||
typedef struct _VipsBinaryClass {
|
typedef struct _VipsBinaryClass {
|
||||||
VipsArithmeticClass parent_class;
|
VipsArithmeticClass parent_class;
|
||||||
|
|
||||||
|
/* The line processor.
|
||||||
|
*/
|
||||||
|
VipsBinaryProcessFn process_line;
|
||||||
|
|
||||||
} VipsBinaryClass;
|
} VipsBinaryClass;
|
||||||
|
|
||||||
GType vips_binary_get_type( void );
|
GType vips_binary_get_type( void );
|
||||||
|
Loading…
Reference in New Issue
Block a user