Example #1
0
int
im_makerw( IMAGE *im )
{
	return( im_rwcheck( im ) );
}
Example #2
0
/* Draw a line on a image with a user plot function. We do no clipping: the
 * user function should check ranges for each pixel when it is called.
 */
int 
im_fastlineuser( IMAGE *im, 
	int x1, int y1, int x2, int y2, 
	int (*fn)(), void *client1, void *client2, void *client3 )
{	
	int x, y, dx, dy;
	int err;

	if( im_rwcheck( im ) )
		return( -1 );

	/* Find offsets.
	 */
	dx = x2 - x1;
	dy = y2 - y1;

	/* Swap endpoints to reduce number of cases. 
	 */
	if( abs( dx ) >= abs( dy ) && dx < 0 ) {
		/* Swap to get all x greater or equal cases going to the 
		 * right. Do diagonals here .. just have up and right and down
		 * and right now.
		 */
		SWAP( x1, x2 );
		SWAP( y1, y2 );
	}
	else if( abs( dx ) < abs( dy ) && dy < 0 ) {
		/* Swap to get all y greater cases going down the screen.
		 */
		SWAP( x1, x2 );
		SWAP( y1, y2 );
	}

	/* Recalculate dx, dy.
	 */
	dx = x2 - x1;
	dy = y2 - y1;

	/* Start point and offset.
	 */
	x = x1; 
	y = y1;

	/* Special case: zero width and height is single point.
	 */
	if( dx == 0 && dy == 0 ) {
		if( fn( im, x, y, client1, client2, client3 ) )
			return( 1 );
	}
	/* Special case vertical and horizontal lines for speed.
	 */
	else if( dx == 0 ) {
		/* Vertical line going down.
		 */
		for( ; y <= y2; y++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
		}
	}
	else if( dy == 0 ) {
		/* Horizontal line to the right.
		 */
		for( ; x <= x2; x++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
		}
	}
	/* Special case diagonal lines.
	 */
	else if( abs( dy ) == abs( dx ) && dy > 0 ) {
		/* Diagonal line going down and right.
		 */
		for( ; x <= x2; x++, y++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
		}
	}
	else if( abs( dy ) == abs( dx ) && dy < 0 ) {
		/* Diagonal line going up and right.
		 */
		for( ; x <= x2; x++, y-- ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
		}
	}
	else if( abs( dy ) < abs( dx ) && dy > 0 ) {
		/* Between -45 and 0 degrees.
		 */
		for( err = 0; x <= x2; x++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
			err += dy;
			if( err >= dx ) {
				err -= dx;
				y++;
			}
		}
	}
	else if( abs( dy ) < abs( dx ) && dy < 0 ) {
		/* Between 0 and 45 degrees.
		 */
		for( err = 0; x <= x2; x++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
			err -= dy;
			if( err >= dx ) {
				err -= dx;
				y--;
			}
		}
	}
	else if( abs( dy ) > abs( dx ) && dx > 0 ) {
		/* Between -45 and -90 degrees.
		 */
		for( err = 0; y <= y2; y++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
			err += dx;
			if( err >= dy ) {
				err -= dy;
				x++;
			}
		}
	}
	else if( abs( dy ) > abs( dx ) && dx < 0 ) {
		/* Between -90 and -135 degrees.
		 */
		for( err = 0; y <= y2; y++ ) {
			if( fn( im, x, y, client1, client2, client3 ) )
				return( 1 );
			err -= dx;
			if( err >= dy ) {
				err -= dy;
				x--;
			}
		}
	}
	else
		error_exit( "internal error #9872659823475982375" );

	return( 0 );
}
Example #3
0
/* Draw a line on a image.
 */
int 
im_fastline( IMAGE *im, int x1, int y1, int x2, int y2, PEL *pel )
{	
	int es = IM_IMAGE_SIZEOF_ELEMENT( im ); 
	int ps = es * im->Bands;
	int ls = ps * im->Xsize;
	PEL *p;

	int x, y, dx, dy;
	int err;
	int b;

	if( im_rwcheck( im ) )
		return( -1 );

	/* Check coordinates in range.
	 */
	if(  x1 > im->Xsize || x1 < 0 || 
		y1 > im->Ysize || y1 < 0 || 
	        x2 > im->Xsize || x2 < 0 || 
		y2 > im->Ysize || y2 < 0 ) { 
		im_error( "im_fastline", "%s", 
			_( "invalid line cooordinates" ) ); 
		return( -1 ); 
	}

	/* Find offsets.
	 */
	dx = x2 - x1;
	dy = y2 - y1;

	/* Swap endpoints to reduce number of cases. 
	 */
	if( abs( dx ) >= abs( dy ) && dx < 0 ) {
		/* Swap to get all x greater or equal cases going to the 
		 * right. Do diagonals here .. just have up and right and down
		 * and right now.
		 */
		SWAP( x1, x2 );
		SWAP( y1, y2 );
	}
	else if( abs( dx ) < abs( dy ) && dy < 0 ) {
		/* Swap to get all y greater cases going down the screen.
		 */
		SWAP( x1, x2 );
		SWAP( y1, y2 );
	}

	/* Recalculate dx, dy.
	 */
	dx = x2 - x1;
	dy = y2 - y1;

	/* Start point and offset.
	 */
	x = x1; 
	y = y1;
	p = (PEL *) im->data + x * ps + y * ls;

	/* Plot point macro.
	 */
#define PLOT \
	for( b = 0; b < ps; b++ ) \
		p[b] = pel[b];

	/* Special case: zero width and height is single point.
	 */
	if( dx == 0 && dy == 0 ) {
		PLOT;
	}
	/* Special case vertical and horizontal lines for speed.
	 */
	else if( dx == 0 ) {
		/* Vertical line going down.
		 */
		for( ; y <= y2; y++ ) {
			PLOT;
			p += ls;
		}
	}
	else if( dy == 0 ) {
		/* Horizontal line to the right.
		 */
		for( ; x <= x2; x++ ) {
			PLOT;
			p += ps;
		}
	}
	/* Special case diagonal lines.
	 */
	else if( abs( dy ) == abs( dx ) && dy > 0 ) {
		/* Diagonal line going down and right.
		 */
		for( ; x <= x2; x++ ) {
			PLOT;
			p += ps + ls;
		}
	}
	else if( abs( dy ) == abs( dx ) && dy < 0 ) {
		/* Diagonal line going up and right.
		 */
		for( ; x <= x2; x++ ) {
			PLOT;
			p += ps - ls;
		}
	}
	else if( abs( dy ) < abs( dx ) && dy > 0 ) {
		/* Between -45 and 0 degrees.
		 */
		for( err = 0; x <= x2; x++ ) {
			PLOT;
			p += ps;
			err += dy;
			if( err >= dx ) {
				err -= dx;
				p += ls;
			}
		}
	}
	else if( abs( dy ) < abs( dx ) && dy < 0 ) {
		/* Between 0 and 45 degrees.
		 */
		for( err = 0; x <= x2; x++ ) {
			PLOT;
			p += ps;
			err -= dy;
			if( err >= dx ) {
				err -= dx;
				p -= ls;
			}
		}
	}
	else if( abs( dy ) > abs( dx ) && dx > 0 ) {
		/* Between -45 and -90 degrees.
		 */
		for( err = 0; y <= y2; y++ ) {
			PLOT;
			p += ls;
			err += dx;
			if( err >= dy ) {
				err -= dy;
				p += ps;
			}
		}
	}
	else if( abs( dy ) > abs( dx ) && dx < 0 ) {
		/* Between -90 and -135 degrees.
		 */
		for( err = 0; y <= y2; y++ ) {
			PLOT;
			p += ls;
			err -= dx;
			if( err >= dy ) {
				err -= dy;
				p -= ps;
			}
		}
	}
	else
		error_exit( "internal error #9872659823475982375" );

	return( 0 );
}
Example #4
0
/* Smear a section of an IMAGE. As above, but shift it left a bit.
 */
int
im_smear( IMAGE *im, int ix, int iy, Rect *r )
{	
	int x, y, a, b, c;
	int ba = im->Bands;
	int el = ba * im->Xsize;
	Rect area, image, clipped;
	double total[ 256 ];

	if( im_rwcheck( im ) )
		return( -1 );

	/* Don't do the margins.
	 */
	area = *r;
	area.left += ix;
	area.top += iy;
	image.left = 0;
	image.top = 0;
	image.width = im->Xsize;
	image.height = im->Ysize;
	im_rect_marginadjust( &image, -1 );
	image.left--;
	im_rect_intersectrect( &area, &image, &clipped );

	/* Any left?
	 */
	if( im_rect_isempty( &clipped ) )
		return( 0 );

/* What we do for each type.
 */
#define SMEAR(TYPE) \
	for( y = clipped.top; y < clipped.top + clipped.height; y++ ) \
		for( x = clipped.left;  \
			x < clipped.left + clipped.width; x++ ) { \
			TYPE *to = (TYPE *) im->data + x * ba + y * el; \
			TYPE *from = to - el; \
			TYPE *f; \
 			\
			for( a = 0; a < ba; a++ ) \
				total[a] = 0.0; \
			\
			for( a = 0; a < 3; a++ ) { \
				f = from; \
				for( b = 0; b < 3; b++ ) \
					for( c = 0; c < ba; c++ ) \
						total[c] += *f++; \
				from += el; \
			} \
 			\
			for( a = 0; a < ba; a++ ) \
				to[a] = (40 * (double) to[a+ba] + total[a]) \
					/ 49.0; \
		}

	/* Loop through the remaining pixels.
	 */
	switch( im->BandFmt ) {
	case IM_BANDFMT_UCHAR: 
		SMEAR(unsigned char); 
		break; 

	case IM_BANDFMT_CHAR: 
		SMEAR(char); 
		break; 

	case IM_BANDFMT_USHORT: 
		SMEAR(unsigned short); 
		break; 

	case IM_BANDFMT_SHORT: 
		SMEAR(short); 
		break; 

	case IM_BANDFMT_UINT: 
		SMEAR(unsigned int); 
		break; 

	case IM_BANDFMT_INT: 
		SMEAR(int); 
		break; 

	case IM_BANDFMT_FLOAT: 
		SMEAR(float); 
		break; 

	case IM_BANDFMT_DOUBLE: 
		SMEAR(double); 
		break; 

	/* Do complex types too. Just treat as float and double, but with
	 * twice the number of bands.
	 */
	case IM_BANDFMT_COMPLEX:
		/* Twice number of bands: double size and bands.
		 */
		ba *= 2;
		el *= 2;

		SMEAR(float);

		break;

	case IM_BANDFMT_DPCOMPLEX:
		/* Twice number of bands: double size and bands.
		 */
		ba *= 2;
		el *= 2;

		SMEAR(double);

		break;

	default:
		im_error( "im_smear", "%s", _( "unknown band format" ) );
		return( -1 );
	}

	return( 0 );
}