diff --git a/libvips/include/vips/vector.h b/libvips/include/vips/vector.h index f3c5cf38..583a315e 100644 --- a/libvips/include/vips/vector.h +++ b/libvips/include/vips/vector.h @@ -108,7 +108,7 @@ VipsVector *vips_vector_new( const char *name, int dsize ); void vips_vector_constant( VipsVector *vector, char *name, int value, int size ); -void vips_vector_source_name( VipsVector *vector, char *name, int size ); +int vips_vector_source_name( VipsVector *vector, char *name, int size ); void vips_vector_source_scanline( VipsVector *vector, char *name, int line, int size ); void vips_vector_temporary( VipsVector *vector, char *name, int size ); diff --git a/libvips/iofuncs/vector.c b/libvips/iofuncs/vector.c index 9ac80bab..b5c5fb16 100644 --- a/libvips/iofuncs/vector.c +++ b/libvips/iofuncs/vector.c @@ -208,16 +208,22 @@ vips_vector_constant( VipsVector *vector, char *name, int value, int size ) #endif /*HAVE_ORC*/ } -void +int vips_vector_source_name( VipsVector *vector, char *name, int size ) { + int var; + #ifdef HAVE_ORC g_assert( orc_program_find_var_by_name( vector->program, name ) == -1 ); - vector->s[vector->n_source] = + vector->s[vector->n_source] = var = orc_program_add_source( vector->program, size, name ); vector->n_source += 1; +#else /*!HAVE_ORC*/ + var = -1; #endif /*HAVE_ORC*/ + + return( var ); } void diff --git a/libvips/morphology/morphology.c b/libvips/morphology/morphology.c index 828c3d34..6880c746 100644 --- a/libvips/morphology/morphology.c +++ b/libvips/morphology/morphology.c @@ -82,6 +82,8 @@ typedef struct { int first; /* The index of the first mask coff we use */ int last; /* The index of the last mask coff we use */ + int r; /* Set previous result in this var */ + /* The code we generate for this section of this mask. */ VipsVector *vector; @@ -134,12 +136,11 @@ morph_close( Morph *morph ) * 0 for success, -1 on error. */ static int -pass_compile_section( Morph *morph, int first, int *last ) +pass_compile_section( Pass *pass, Morph *morph, gboolean first_pass ) { INTMASK *mask = morph->mask; const int n_mask = mask->xsize * mask->ysize; - Pass *pass; VipsVector *v; char offset[256]; char source[256]; @@ -147,14 +148,6 @@ pass_compile_section( Morph *morph, int first, int *last ) char one[256]; int i; - /* Allocate space for another pass. - */ - if( morph->n_pass == MAX_PASSES ) - return( -1 ); - pass = &morph->pass[morph->n_pass]; - morph->n_pass += 1; - pass->first = first; - pass->vector = v = vips_vector_new( "morph", 1 ); /* The value we fetch from the image, the accumulated sum. @@ -169,20 +162,20 @@ pass_compile_section( Morph *morph, int first, int *last ) * is a later pass, we have to init the sum from the result * of the previous pass. */ - if( morph->n_pass == 1 ) { + if( first_pass ) { if( morph->op == DILATE ) ASM2( "copyb", "sum", zero ); else ASM2( "copyb", "sum", one ); } else { - /* "r" is the result of the previous pass. var in s[1]. + /* "r" is the result of the previous pass. */ - vips_vector_source_name( v, "r", 1 ); + pass->r = vips_vector_source_name( v, "r", 1 ); ASM2( "loadb", "sum", "r" ); } - for( i = first; i < n_mask; i++ ) { + for( i = pass->first; i < n_mask; i++ ) { int x = i % mask->xsize; int y = i / mask->xsize; @@ -224,7 +217,6 @@ pass_compile_section( Morph *morph, int first, int *last ) } pass->last = i; - *last = i; ASM2( "copyb", "d1", "sum" ); @@ -248,6 +240,7 @@ pass_compile( Morph *morph ) const int n_mask = mask->xsize * mask->ysize; int i; + Pass *pass; #ifdef DEBUG printf( "morph: generating vector code\n" ); @@ -256,8 +249,6 @@ pass_compile( Morph *morph ) /* Generate passes until we've used up the whole mask. */ for( i = 0;;) { - int last; - /* Skip any don't-care coefficients at the start of the mask * region. */ @@ -266,9 +257,20 @@ pass_compile( Morph *morph ) if( i == n_mask ) break; - if( pass_compile_section( morph, i, &last ) ) + /* Allocate space for another pass. + */ + if( morph->n_pass == MAX_PASSES ) return( -1 ); - i = last + 1; + pass = &morph->pass[morph->n_pass]; + morph->n_pass += 1; + + pass->first = i; + pass->last = i; + pass->r = -1; + + if( pass_compile_section( pass, morph, morph->n_pass == 1 ) ) + return( -1 ); + i = pass->last + 1; if( i >= n_mask ) break; @@ -673,7 +675,7 @@ morph_vector_gen( REGION *or, void *vseq, void *a, void *b ) vips_executor_set_scanline( &executor[j], ir, r->left, r->top + y ); vips_executor_set_array( &executor[j], - morph->pass[j].vector->s[1], seq->t1 ); + morph->pass[j].r, seq->t1 ); vips_executor_set_destination( &executor[j], d ); vips_executor_run( &executor[j] );