www.pudn.com > CXIMAGE_SRC.ZIP > ximasel.cpp


// xImaSel.cpp : Selection functions 
/* 07/08/2001 v1.00 - ing.davide.pizzolato@libero.it 
 * CxImage version 5.00 23/Aug/2002 
 */ 
 
#include "ximage.h" 
 
#if CXIMAGE_SUPPORT_SELECTION 
 
//////////////////////////////////////////////////////////////////////////////// 
void CxImage::SelectionClear() 
{ 
	if (pSelection){ 
		memset(pSelection,0,head.biWidth * head.biHeight); 
		info.rSelectionBox.left = head.biWidth; 
		info.rSelectionBox.bottom = head.biHeight; 
		info.rSelectionBox.right = info.rSelectionBox.top = 0; 
	} 
} 
//////////////////////////////////////////////////////////////////////////////// 
void CxImage::SelectionCreate() 
{ 
	SelectionDelete(); 
	pSelection = (BYTE*)calloc(head.biWidth * head.biHeight, 1); 
} 
//////////////////////////////////////////////////////////////////////////////// 
void CxImage::SelectionDelete() 
{ 
	if (pSelection){ free(pSelection); pSelection=NULL; } 
	info.rSelectionBox.left = head.biWidth; 
	info.rSelectionBox.bottom = head.biHeight; 
	info.rSelectionBox.right = info.rSelectionBox.top = 0; 
} 
//////////////////////////////////////////////////////////////////////////////// 
bool CxImage::IsInsideSelection(long x, long y) 
{ 
	if (IsInside(x,y)){ 
		if (pSelection==NULL) return true; 
		return pSelection[x+y*head.biWidth]!=0; 
	} return false; 
} 
//////////////////////////////////////////////////////////////////////////////// 
void CxImage::SelectionAddRect(RECT r) 
{ 
	if (pSelection==NULL) SelectionCreate(); 
 
	RECT r2; 
	if (r.left r2.left) info.rSelectionBox.left = max(0L,min(head.biWidth,r2.left)); 
	if (info.rSelectionBox.right < r2.left) info.rSelectionBox.right = max(0L,min(head.biWidth,r2.right)); 
	if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0L,min(head.biHeight,r2.bottom)); 
 
	long ymin = max(0L,min(head.biHeight,r2.bottom)); 
	long ymax = max(0L,min(head.biHeight,r2.top)); 
	long xmin = max(0L,min(head.biWidth,r2.left)); 
	long xmax = max(0L,min(head.biWidth,r2.right)); 
 
	for (long y=ymin; y (xcenter - xradius)) info.rSelectionBox.left = max(0L,min(head.biWidth,(xcenter - xradius))); 
	if (info.rSelectionBox.right < (xcenter + xradius)) info.rSelectionBox.right = max(0L,min(head.biWidth,(xcenter + xradius))); 
	if (info.rSelectionBox.bottom > (ycenter - yradius)) info.rSelectionBox.bottom = max(0L,min(head.biHeight,(ycenter - yradius))); 
	if (info.rSelectionBox.top < (ycenter + yradius)) info.rSelectionBox.top = max(0L,min(head.biHeight,(ycenter + yradius))); 
 
	long xmin = max(0L,min(head.biWidth,xcenter - xradius)); 
	long xmax = max(0L,min(head.biWidth,xcenter + xradius)); 
	long ymin = max(0L,min(head.biHeight,ycenter - yradius)); 
	long ymax = max(0L,min(head.biHeight,ycenter + yradius)); 
 
	long y,yo; 
	for (y=ymin; yy) pSelection[x + y * head.biWidth] = 255; 
		} 
	} 
} 
//////////////////////////////////////////////////////////////////////////////// 
void CxImage::SelectionInvert() 
{ 
	if (pSelection) { 
		BYTE *iSrc=pSelection; 
		long n=head.biHeight*head.biWidth; 
		for(long i=0; i < n; i++){ 
			*iSrc=(BYTE)~(*(iSrc)); 
			iSrc++; 
		} 
	} 
} 
//////////////////////////////////////////////////////////////////////////////// 
bool CxImage::SelectionCopy(CxImage &from) 
{ 
	if (from.pSelection == NULL || head.biWidth != from.head.biWidth || head.biWidth != from.head.biWidth) return false; 
	if (pSelection==NULL) pSelection = (BYTE*)malloc(head.biWidth * head.biHeight); 
	memcpy(pSelection,from.pSelection,head.biWidth * head.biHeight); 
	memcpy(&info.rSelectionBox,&from.info.rSelectionBox,sizeof(RECT)); 
	return true; 
} 
//////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////// 
void CxImage::SelectionAddPolygon(POINT *points, long npoints) 
{ 
	if (points==NULL || npoints<3) return; 
 
	if (pSelection==NULL) SelectionCreate(); 
	BYTE* plocal = (BYTE*)calloc(head.biWidth*head.biHeight, 1); 
	RECT localbox = {head.biWidth,0,0,head.biHeight}; 
 
	long i=0; 
	POINT *current,*next,*start; 
	//trace contour 
	while (i < npoints){ 
		current = &points[i]; 
		if (current->x!=-1){ 
			if (i==0 || (i>0 && points[i-1].x==-1)) start = &points[i]; 
 
			if ((i+1)==npoints || points[i+1].x==-1) 
				next = start; 
			else 
				next = &points[i+1]; 
 
			long x,y; 
			float beta; 
			if (current->x != next->x){ 
				beta = (float)(next->y - current->y)/(float)(next->x - current->x); 
				if (current->x < next->x){ 
					for (x=current->x; x<=next->x; x++){ 
						y = (long)(current->y + (x - current->x) * beta); 
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; 
					} 
				} else { 
					for (x=current->x; x>=next->x; x--){ 
						y = (long)(current->y + (x - current->x) * beta); 
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; 
					} 
				} 
			} 
			if (current->y != next->y){ 
				beta = (float)(next->x - current->x)/(float)(next->y - current->y); 
				if (current->y < next->y){ 
					for (y=current->y; y<=next->y; y++){ 
						x = (long)(current->x + (y - current->y) * beta); 
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; 
					} 
				} else { 
					for (y=current->y; y>=next->y; y--){ 
						x = (long)(current->x + (y - current->y) * beta); 
						if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255; 
					} 
				} 
			} 
		} 
 
		RECT r2; 
		if (current->x < next->x) {r2.left=current->x; r2.right=next->x; } else {r2.left=next->x ; r2.right=current->x; } 
		if (current->y < next->y) {r2.bottom=current->y; r2.top=next->y; } else {r2.bottom=next->y ; r2.top=current->y; } 
		if (localbox.top < r2.top) localbox.top = max(0L,min(head.biHeight-1,r2.top+1)); 
		if (localbox.left > r2.left) localbox.left = max(0L,min(head.biWidth-1,r2.left-1)); 
		if (localbox.right < r2.right) localbox.right = max(0L,min(head.biWidth-1,r2.right+1)); 
		if (localbox.bottom > r2.bottom) localbox.bottom = max(0L,min(head.biHeight-1,r2.bottom-1)); 
 
		i++; 
	} 
	 
	//fill the outer region 
	long npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom); 
	POINT* pix = (POINT*)calloc(npix,sizeof(POINT)); 
	BYTE back=0, mark=1; 
	long fx, fy, first, last,x,y,xmin,xmax,ymin,ymax; 
 
	for (int side=0; side<4; side++){ 
		switch(side){ 
		case 0: 
			xmin=localbox.left; xmax=localbox.right; ymin=localbox.bottom; ymax=localbox.bottom+1; 
			break; 
		case 1: 
			xmin=localbox.right; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.top; 
			break; 
		case 2: 
			xmin=localbox.left; xmax=localbox.right; ymin=localbox.top; ymax=localbox.top+1; 
			break; 
		case 3: 
			xmin=localbox.left; xmax=localbox.left+1; ymin=localbox.bottom; ymax=localbox.top; 
			break; 
		} 
		//fill from the border points 
		for(y=ymin;y=localbox.left && (x + fx)=localbox.bottom && (y + fy)=localbox.left && (x + fx)=localbox.bottom && (y + fy) localbox.left) info.rSelectionBox.left = localbox.left; 
	if (info.rSelectionBox.right < localbox.left) info.rSelectionBox.right = localbox.right; 
	if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom; 
 
	free(plocal); 
	free(pix); 
} 
//////////////////////////////////////////////////////////////////////////////// 
#endif //CXIMAGE_SUPPORT_SELECTION