Ejemplo n.º 1
0
/*ARGSUSED*/
static int
gnoise_gen( REGION *or, void *seq, void *a, void *b )
{
	GnoiseInfo *gin = (GnoiseInfo *) a;
	int x, y, i;
	int sz = IM_REGION_N_ELEMENTS( or );

	for( y = 0; y < or->valid.height; y++ ) {
		float *q = (float *) 
			IM_REGION_ADDR( or, or->valid.left, y + or->valid.top );

		for( x = 0; x < sz; x++ ) {
			double sum = 0.0;

			for( i = 0; i < 12; i++ ) 
#ifdef HAVE_RANDOM
				sum += (double) random() / RAND_MAX;
#else /*HAVE_RANDOM*/
#ifdef HAVE_RAND
				sum += (double) rand() / RAND_MAX;
#else /*HAVE_RAND*/
#error "no random number generator found"
#endif /*HAVE_RAND*/
#endif /*HAVE_RAND*/

			q[x] = (sum - 6.0) * gin->sigma + gin->mean;
		}
	}

	return( 0 );
}
Ejemplo n.º 2
0
/* The vector codepath.
 */
static int
morph_vector_gen( REGION *or, void *vseq, void *a, void *b )
{
	MorphSequence *seq = (MorphSequence *) vseq;
	Morph *morph = (Morph *) b;
	INTMASK *mask = morph->mask;
	REGION *ir = seq->ir;
	Rect *r = &or->valid;
	int sz = IM_REGION_N_ELEMENTS( or );

	Rect s;
	int y, j;
	VipsExecutor executor[MAX_PASS];

	/* Prepare the section of the input image we need. A little larger
	 * than the section of the output image we are producing.
	 */
	s = *r;
	s.width += mask->xsize - 1;
	s.height += mask->ysize - 1;
	if( im_prepare( ir, &s ) )
		return( -1 );

#ifdef DEBUG
	printf( "morph_vector_gen: preparing %dx%d@%dx%d pixels\n", 
		s.width, s.height, s.left, s.top );
#endif /*DEBUG*/

	for( j = 0; j < morph->n_pass; j++ ) 
		vips_executor_set_program( &executor[j], 
			morph->pass[j].vector, sz );

	for( y = 0; y < r->height; y++ ) { 
		for( j = 0; j < morph->n_pass; j++ ) {
			void *d;

			/* The last pass goes to the output image,
			 * intermediate passes go to t2.
			 */
			if( j == morph->n_pass - 1 )
				d = IM_REGION_ADDR( or, r->left, r->top + y );
			else 
				d = seq->t2;

			vips_executor_set_scanline( &executor[j], 
				ir, r->left, r->top + y );
			vips_executor_set_array( &executor[j],
				morph->pass[j].r, seq->t1 );
			vips_executor_set_destination( &executor[j], d );
			vips_executor_run( &executor[j] );

			IM_SWAP( void *, seq->t1, seq->t2 );
		}
	}

	return( 0 );
}
Ejemplo n.º 3
0
/* Loop over region, adding to seq.
 */
static int
maxposavg_scan( REGION *reg, void *seq, void *a, void *b, gboolean *stop )
{
	const Rect *r = &reg->valid;
	const int sz = IM_REGION_N_ELEMENTS( reg );
	Maxposavg *maxposavg = (Maxposavg *) seq;

	int x, y;
	double max;
	int xpos, ypos, occurences;

	xpos = maxposavg->xpos;
	ypos = maxposavg->ypos;
	max = maxposavg->max;
	occurences = maxposavg->occurences;

	for( y = 0; y < r->height; y++ ) { 
		VipsPel *in = VIPS_REGION_ADDR( reg, r->left, r->top + y ); 

		switch( reg->im->BandFmt ) {
		case IM_BANDFMT_UCHAR:		LOOP( unsigned char ); break; 
		case IM_BANDFMT_CHAR:		LOOP( signed char ); break; 
		case IM_BANDFMT_USHORT:		LOOP( unsigned short ); break; 
		case IM_BANDFMT_SHORT:		LOOP( signed short ); break; 
		case IM_BANDFMT_UINT:		LOOP( unsigned int ); break;
		case IM_BANDFMT_INT:		LOOP( signed int ); break; 
		case IM_BANDFMT_FLOAT:		LOOP( float ); break; 
		case IM_BANDFMT_DOUBLE:		LOOP( double ); break; 
		case IM_BANDFMT_COMPLEX:	CLOOP( float ); break; 
		case IM_BANDFMT_DPCOMPLEX:	CLOOP( double ); break; 

		default:  
			g_assert( 0 );
		}
	} 

	maxposavg->xpos = xpos;
	maxposavg->ypos = ypos;
	maxposavg->max = max;
	maxposavg->occurences = occurences;

	return( 0 );
}
Ejemplo n.º 4
0
/* Do a map.
 */
static int 
maplut_gen( REGION *or, void *vseq, void *a, void *b )
{
	Seq *seq = (Seq *) vseq;
	IMAGE *in = (IMAGE *) a;
	LutInfo *st = (LutInfo *) b;
	REGION *ir = seq->ir;
	Rect *r = &or->valid;
	int le = r->left;
	int to = r->top;
	int bo = IM_RECT_BOTTOM(r);
	int np = r->width;			/* Pels across region */
	int ne = IM_REGION_N_ELEMENTS( or );	/* Number of elements */
	int x, y, z, i;

	/* Get input ready.
	 */
	if( im_prepare( ir, r ) )
		return( -1 );

	/* Process!
	 */
	if( st->nb == 1 )
		/* One band lut.
		 */
		outer_switch( loop1, loop1c, loop1g, loop1cg ) 
	else 
		/* Many band lut.
		 */
		if( ir->im->Bands == 1 )
			/* ... but 1 band input.
			 */
			outer_switch( loop1m, loop1cm, loop1gm, loop1cgm ) 
		else
			outer_switch( loop, loopc, loopg, loopcg )

	return( 0 );
}
Ejemplo n.º 5
0
/* Loop over region, adding information to the appropriate fields of tmp.
 */
static int
scan_fn( REGION *reg, void *seq, void *a, void *b )
{	
	double *tmp = (double *) seq;
	Rect *r = &reg->valid;
	IMAGE *im = reg->im;
	int le = r->left;
	int to = r->top;
	int bo = IM_RECT_BOTTOM(r);
	int sz = IM_REGION_N_ELEMENTS( reg );
	double s = 0.0;
	double s2 = 0.0;
	int x, y;

/* Sum pels in this section.
 */
#define loop(TYPE) \
	{	TYPE *p; \
 		\
		for( y = to; y < bo; y++ ) { \
			p = (TYPE *) IM_REGION_ADDR( reg, le, y ); \
			\
			for( x = 0; x < sz; x++ ) { \
				TYPE v = p[x]; \
				\
				s += v; \
				s2 += (double) v * (double) v; \
			}\
		}\
	}

	/* Now generate code for all types. 
	 */
	switch( im->BandFmt ) {
	case IM_BANDFMT_UCHAR:		loop(unsigned char); break; 
	case IM_BANDFMT_CHAR:		loop(signed char); break; 
	case IM_BANDFMT_USHORT:		loop(unsigned short); break; 
	case IM_BANDFMT_SHORT:		loop(signed short); break; 
	case IM_BANDFMT_UINT:		loop(unsigned int); break; 
	case IM_BANDFMT_INT:		loop(signed int); break; 
	case IM_BANDFMT_FLOAT:		loop(float); break; 

	case IM_BANDFMT_DOUBLE:	
#ifdef HAVE_LIBOIL
		for( y = to; y < bo; y++ ) { 
			double *p = (double *) IM_REGION_ADDR( reg, le, y ); 
			double t;
			double t2;

			oil_sum_f64( &t, p, sizeof( double ), sz );
			oil_squaresum_f64( &t2, p, sz );

			s += t;
			s2 += t2;
		}
#else /*!HAVE_LIBOIL*/
		loop(double); 
#endif /*HAVE_LIBOIL*/
		break; 

	default: 
		assert( 0 );
	}

	/* Add to sum for this sequence.
	 */
	tmp[0] += s;
	tmp[1] += s2;

	return( 0 );
}
Ejemplo n.º 6
0
/* Erode!
 */
static int
erode_gen( REGION *or, void *vseq, void *a, void *b )
{
	MorphSequence *seq = (MorphSequence *) vseq;
	Morph *morph = (Morph *) b;
	INTMASK *mask = morph->mask;
	REGION *ir = seq->ir;

	int *soff = seq->soff;
	int *coff = seq->coff;

	Rect *r = &or->valid;
	Rect s;
	int le = r->left;
	int to = r->top;
	int bo = IM_RECT_BOTTOM(r);
	int sz = IM_REGION_N_ELEMENTS( or );

	int *t;

	int x, y;
	int result, i;

	/* Prepare the section of the input image we need. A little larger
	 * than the section of the output image we are producing.
	 */
	s = *r;
	s.width += mask->xsize - 1;
	s.height += mask->ysize - 1;
	if( im_prepare( ir, &s ) )
		return( -1 );

#ifdef DEBUG
	printf( "erode_gen: preparing %dx%d@%dx%d pixels\n", 
		s.width, s.height, s.left, s.top );
#endif /*DEBUG*/

	/* Scan mask, building offsets we check when processing. Only do this
	 * if the bpl has changed since the previous im_prepare().
	 */
	if( seq->last_bpl != IM_REGION_LSKIP( ir ) ) {
		seq->last_bpl = IM_REGION_LSKIP( ir );

		seq->ss = 0;
		seq->cs = 0;
		for( t = mask->coeff, y = 0; y < mask->ysize; y++ )
			for( x = 0; x < mask->xsize; x++, t++ )
				switch( *t ) {
				case 255:
					soff[seq->ss++] = 
						IM_REGION_ADDR( ir, 
							x + le, y + to ) - 
						IM_REGION_ADDR( ir, le, to );
					break;

				case 128:
					break;

				case 0:
					coff[seq->cs++] = 
						IM_REGION_ADDR( ir, 
							x + le, y + to ) - 
						IM_REGION_ADDR( ir, le, to );
					break;

				default:
					g_assert( 0 );
				}
	}

	/* Erode!
	 */
	for( y = to; y < bo; y++ ) {
		VipsPel *p = IM_REGION_ADDR( ir, le, y );
		VipsPel *q = IM_REGION_ADDR( or, le, y );

		/* Loop along line.
		 */
		for( x = 0; x < sz; x++, q++, p++ ) {
			/* Check all set pixels are set.
			 */
			result = 255;
			for( i = 0; i < seq->ss; i++ )
				if( !p[soff[i]] ) {
					/* Found a mismatch! 
					 */
					result = 0;
					break;
				}

			/* Check all clear pixels are clear.
			 */
			if( result )
				for( i = 0; i < seq->cs; i++ )
					if( p[coff[i]] ) {
						result = 0;
						break;
					}

			*q = result;
		}
	}
	
	return( 0 );
}
Ejemplo n.º 7
0
/* Dilate!
 */
static int
dilate_gen( REGION *or, void *vseq, void *a, void *b )
{
	SeqInfo *seq = (SeqInfo *) vseq;
	INTMASK *msk = (INTMASK *) b;
	REGION *ir = seq->ir;

	int *soff = seq->soff;
	int *coff = seq->coff;

	Rect *r = &or->valid;
	Rect s;
	int le = r->left;
	int to = r->top;
	int bo = IM_RECT_BOTTOM(r);
	int sz = IM_REGION_N_ELEMENTS( or );

	int *t;

	int x, y;
	int result, i;

	/* Prepare the section of the input image we need. A little larger
	 * than the section of the output image we are producing.
	 */
	s = *r;
	s.width += msk->xsize - 1;
	s.height += msk->ysize - 1;
	if( im_prepare( ir, &s ) )
		return( -1 );

#ifdef DEBUG
	printf( "erode_gen: preparing %dx%d pixels\n", s.width, s.height );
#endif /*DEBUG*/

	/* Scan mask, building offsets we check when processing. Only do this
	 * if the bpl has changed since the previous im_prepare().
	 */
	if( seq->last_bpl != IM_REGION_LSKIP( ir ) ) {
		seq->last_bpl = IM_REGION_LSKIP( ir );

		seq->ss = 0;
		seq->cs = 0;
		for( t = msk->coeff, y = 0; y < msk->ysize; y++ )
			for( x = 0; x < msk->xsize; x++, t++ )
				switch( *t ) {
				case 255:
					soff[seq->ss++] = 
						IM_REGION_ADDR( ir, 
							x + le, y + to ) - 
						IM_REGION_ADDR( ir, le, to );
					break;

				case 128:
					break;

				case 0:
					coff[seq->cs++] = 
						IM_REGION_ADDR( ir, 
							x + le, y + to ) - 
						IM_REGION_ADDR( ir, le, to );
					break;

				default:
					im_error( "im_dilate", 
						_( "bad mask element (%d "
						"should be 0, 128 or 255)" ), 
						*t );
					return( -1 ); 
				}
	}

	/* Dilate!
	 */
	for( y = to; y < bo; y++ ) {
		PEL *p = (PEL *) IM_REGION_ADDR( ir, le, y );
		PEL *q = (PEL *) IM_REGION_ADDR( or, le, y );

		/* Loop along line.
		 */
		for( x = 0; x < sz; x++, q++, p++ ) {
			/* Search for a hit on the set list.
			 */
			result = 0;
			for( i = 0; i < seq->ss; i++ )
				if( p[soff[i]] ) {
					/* Found a match! 
					 */
					result = 255;
					break;
				}

			/* No set pixels ... search for a hit in the clear
			 * pixels.
			 */
			if( !result )
				for( i = 0; i < seq->cs; i++ )
					if( !p[coff[i]] ) {
						/* Found a match! 
						 */
						result = 255;
						break;
					}

			*q = result;

		}
	}

	return( 0 );
}
Ejemplo n.º 8
0
/* Loop over region, adding to seq.
 */
static int
scan_fn( REGION *reg, void *vseq, void *a, void *b )
{
	Seq *seq = (Seq *) vseq;
	Rect *r = &reg->valid;
	IMAGE *im = reg->im;
	int le = r->left;
	int to = r->top;
	int bo = IM_RECT_BOTTOM(r);
	int nel = IM_REGION_N_ELEMENTS( reg );

	int x, y;

	double m;

#ifdef DEBUG
	printf( "im_min: left = %d, top = %d, width = %d, height = %d\n",
		r->left, r->top, r->width, r->height );
#endif /*DEBUG*/

#define loop(TYPE) { \
	m = *((TYPE *) IM_REGION_ADDR( reg, le, to )); \
	\
	for( y = to; y < bo; y++ ) { \
		TYPE *p = (TYPE *) IM_REGION_ADDR( reg, le, y ); \
		\
		for( x = 0; x < nel; x++ ) { \
			double v = p[x]; \
			\
			if( v < m ) \
				m = v; \
		} \
	} \
} 

#define complex_loop(TYPE) { \
	TYPE *p = (TYPE *) IM_REGION_ADDR( reg, le, to ); \
	double real = p[0]; \
	double imag = p[1]; \
	\
	m = real * real + imag * imag; \
	\
	for( y = to; y < bo; y++ ) { \
		TYPE *p = (TYPE *) IM_REGION_ADDR( reg, le, y ); \
		\
		for( x = 0; x < nel * 2; x += 2 ) { \
			double mod; \
			\
			real = p[x]; \
			imag = p[x + 1]; \
			mod = real * real + imag * imag; \
			\
			if( mod < m ) \
				m = mod; \
		} \
	} \
} 

	switch( im->BandFmt ) {
	case IM_BANDFMT_UCHAR:		loop( unsigned char ); break; 
	case IM_BANDFMT_CHAR:		loop( signed char ); break; 
	case IM_BANDFMT_USHORT:		loop( unsigned short ); break; 
	case IM_BANDFMT_SHORT:		loop( signed short ); break; 
	case IM_BANDFMT_UINT:		loop( unsigned int ); break;
	case IM_BANDFMT_INT:		loop( signed int ); break; 
	case IM_BANDFMT_FLOAT:		loop( float ); break; 
	case IM_BANDFMT_DOUBLE:		loop( double ); break; 
	case IM_BANDFMT_COMPLEX:	complex_loop( float ); break; 
	case IM_BANDFMT_DPCOMPLEX:	complex_loop( double ); break; 

	default:  
		assert( 0 );
	}

	if( seq->valid ) {
		seq->value = IM_MIN( seq->value, m ); 
	}
	else {
		seq->value = m;
		seq->valid = 1;
	}

	return( 0 );
}