Exemplo n.º 1
0
BOOL InvertImage(LPIMAGE lpImage, LPCMD_PARMS lpParms)
{
	ENGINE Engine;
	FRMTYPEINFO TypeInfo;
	LPCOLORMAP lpColorMap;

	ImgGetTypeInfo(lpImage, &TypeInfo);
	if (TypeInfo.DataType == FDT_PALETTECOLOR)
	{
		lpColorMap = FrameCopyColorMap(TypeInfo.ColorMap);
		if (!lpColorMap)
			{
			Message(IDS_EMEMALLOC);
			lpParms->Common.StatusCode = SC_MEMERROR;
			return(FALSE);
			}
		negate((LPTR)lpColorMap->RGBData, sizeof(RGBS)*lpColorMap->NumEntries);
		lpParms->Common.StatusCode = ApplyColorMap(lpImage, lpColorMap, FALSE, DT_NONE, lpParms->Common.idDirty);
		FrameDestroyColorMap(lpColorMap);
		if (lpParms->Common.StatusCode == SC_SUCCESS)
			lpParms->Common.UpdateType = UT_DATATYPE;
	}
	else
	{
		SetEngineDef(&Engine);
		Engine.lpDataProc = invert_proc;
		lpParms->Common.StatusCode = LineEngineSelObj(lpImage,&Engine,lpParms->Common.idDirty);
		if (!AstralIsRectEmpty(&Engine.rUpdate))
		{
			lpParms->Common.UpdateType = UT_AREA;
			lpParms->Common.rUpdateArea = Engine.rUpdate;
		}
	}
	return(lpParms->Common.StatusCode == SC_SUCCESS);
}
Exemplo n.º 2
0
BOOL TintFillImage(
	LPIMAGE     lpImage,
	LPTINTFILL_PARMS lpParms)
{
	ENGINE Engine;

	SetEngineColor(&Engine, &lpParms->Color, lpParms->FillOpacity,
					lpParms->FillMergeMode);
	lpParms->Common.StatusCode = LineEngineSelObj(lpImage,&Engine,lpParms->Common.idDirty);
	if (!AstralIsRectEmpty(&Engine.rUpdate))
	{
		lpParms->Common.UpdateType = UT_AREA;
		lpParms->Common.rUpdateArea = Engine.rUpdate;
	}
	return(lpParms->Common.StatusCode == SC_SUCCESS);
}
Exemplo n.º 3
0
LOCAL STATUS_CODE ApplyMaps(LPIMAGE lpImage, LPMAPS lpMaps, ITEMID idDirty,
						LPRECT lpUpdateRect, LPUPDATE_TYPE lpUpdateType)
/************************************************************************/
{
	ENGINE Engine;
	FRMTYPEINFO TypeInfo;
	LPCOLORMAP lpColorMap;
	STATUS_CODE StatusCode;

	AstralSetRectEmpty(lpUpdateRect);
	*lpUpdateType = UT_NONE;
	ImgGetTypeInfo(lpImage, &TypeInfo);
	if (TypeInfo.DataType == FDT_PALETTECOLOR)
	{
		lpColorMap = FrameCopyColorMap(TypeInfo.ColorMap);
		if (!lpColorMap)
		{
			Message(IDS_EMEMALLOC);
			return(SC_MEMERROR);
		}
		ApplyMaps24((LPTR)lpColorMap->RGBData, lpColorMap->NumEntries, lpMaps);
		StatusCode = ApplyColorMap(lpImage, lpColorMap, FALSE, DT_NONE, idDirty);
		FrameDestroyColorMap(lpColorMap);
		if (StatusCode == SC_SUCCESS)
			*lpUpdateType = UT_DATATYPE;
	}
	else
	{
		SetEngineDef(&Engine);
		Engine.lpDataProc = (LPDATAPROC)ApplyMapsProc;
		Engine.lpParam = lpMaps;
		StatusCode = LineEngineSelObj(lpImage, &Engine, idDirty);
		if (!AstralIsRectEmpty(&Engine.rUpdate))
		{
			*lpUpdateRect = Engine.rUpdate;
			*lpUpdateType = UT_AREA;
		}
	}
	return(StatusCode);
}
Exemplo n.º 4
0
BOOL TextureFillImage(
	LPIMAGE lpImage,
	LPTEXTUREFILL_PARMS lpParms)
{
	ENGINE Engine;
	FNAME szFileName;
	LPFRAME lpTexture;
	FRMTYPEINFO TypeInfo;

	ImgGetTypeInfo(lpImage, &TypeInfo);

	if (!LookupExtFile(lpParms->TextureName, szFileName, IDN_TEXTURE))
	{
		lpParms->Common.StatusCode = SC_FILENOTFOUND;
		return(FALSE);
	}
	ProgressBegin(2, lpParms->Common.idDirty-IDS_UNDOFIRST+IDS_PROGFIRST);
	CReadImage read(szFileName);
	if ( !(lpTexture = read.ReadFrame(TypeInfo) ))
	{
		ProgressEnd();
		lpParms->Common.StatusCode = SC_READERROR;
		return(FALSE);
	}

	SetEngineOld(&Engine, NO, NULL, NULL, lpTexture,
		lpParms->fHorzFlip, lpParms->fVertFlip,
		NULL, NULL, lpParms->TextureOpacity, lpParms->TextureMergeMode);
	lpParms->Common.StatusCode = LineEngineSelObj(lpImage,&Engine,lpParms->Common.idDirty);
	if (!AstralIsRectEmpty(&Engine.rUpdate))
	{
 		lpParms->Common.UpdateType = UT_AREA;
		lpParms->Common.rUpdateArea = Engine.rUpdate;
	}
	ProgressEnd();
	return(lpParms->Common.StatusCode == SC_SUCCESS);
}
Exemplo n.º 5
0
void CImage::EditUndo( BOOL fEditUndo, BOOL fMaskUndo,
					LPUPDATE_TYPE lpUpdateType, LPRECT lpUpdateRect)
{
RECT rUndo, rUndoMask, rTemp;
LPOBJECT lpBase, lpObject, lpNext;
BOOL fNewSize, fSetupMiniViews, fRemoveMarquee, fUndoDelete, fColorMapChanged;
BOOL fUndoAlpha, fUndoData;
int nDeleted;
LPMASK lpMask;
EDIT_TARGET Target;

AstralSetRectEmpty(lpUpdateRect);

// Initialize things for updating the display
fNewSize = fSetupMiniViews = fUndoDelete = fColorMapChanged = NO;
AstralSetRectEmpty(&rUndo);
AstralSetRectEmpty(&rUndoMask);

// loop through objects doing undo
lpBase = GetBase();
lpObject = NULL;
// get the target of the last edit
Target = EditTarget;
while (lpObject = GetNextObject(lpObject, NO, NO, fEditUndo))
	{
	// See if this is an object we are undoing
	if (fEditUndo)
		{
		// check for special undo processing of a deleted object
		if (lpObject->fDeleted) 
			continue; // do no undo processing for a deleted object
//			{
//			if (Control.UndoObjects && !IsSelectedObject(lpBase))
//				continue;
//			}
		else
		// if target is not the entire image and we are in undo
		// object mode and the object is not selected then
		// skip this object
		if (Target != ET_ALLOBJECTS && Control.UndoObjects && !IsSelectedObject(lpObject))
			continue;
		}
	// Only handle mask undo for the base object
	if (fMaskUndo)
		{
		if (lpObject != lpBase || lpObject->fBothDirty ||
			!lpObject->AlphaDirty)
		continue;
		}

	fUndoData = fUndoAlpha = NO;

	// Do preprocess for doing a data undo
	if (fEditUndo)
		{
		if (lpObject->DataDirty)
			fUndoData = YES;
		// See if we need to undo the alpha for this object
		if ((lpObject != lpBase) && lpObject->lpAlpha && lpObject->AlphaDirty)
			fUndoAlpha = YES;
		if (!fUndoData && !fUndoAlpha)
			continue;
	
		// check to see and undoing/redoing deleted objects will change
		// the select state, if so undraw the object marquee
		if (lpObject == lpBase &&
			lpObject->DataUndoType & UT_DELETEOBJECTS)
			{
			fUndoDelete = YES;
			fRemoveMarquee = NO;
			nDeleted = 0;
			lpNext = lpObject;
			while (lpNext = GetNextObject(lpNext, YES, NO, YES))
				{
				if (lpNext->fUndoDeleted)
					++nDeleted;
				else
				if (lpNext->fDeleted && lpNext->fSelected)
					{
					fRemoveMarquee = YES;
					break;
					}
				}
			if (GetSelObject(NULL) == lpBase && !fRemoveMarquee)
				{
				if (CountObjects() - nDeleted <= 1)
					fRemoveMarquee = YES;
				}
			if (fRemoveMarquee)
				{
				GetObjectMarqueeRect(this, &rTemp);
				AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp);
				}
			}
		}
	else // fMaskUndo
	if (!lpObject->AlphaDirty)
		continue;
	else
		fUndoAlpha = YES;

	// do a preprocess for undoing the mask caused either by
	// a mask undo or by an edit function that also edits the mask
	if (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) ||
		fMaskUndo)
		{
		if ( lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) )
			{
			// if the undo is going to delete the mask,
			// we need to undraw the mask
			if (GetMask())
				{
				GetMaskMarqueeRect(this, &rTemp);
				AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp);
				if (GetMaskUpdateRect(YES, NO, &rTemp))
					AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp);
				}
			// if the undo is going to create the mask,
			// we need to undraw the object marquees if
			// not in mask and object marquee mode
			else
				{
				if (!Control.UseMaskAndObjects)
					{
					GetObjectMarqueeRect(this, &rTemp);
					AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp);
					}
				}
			}
		}

	// Actually do the undo
	ObjEditUndo(lpObject, fUndoData, fUndoAlpha);

	// do a postprocess for undoing the mask
	if ((lpMask = GetMask()) &&
		(((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) ||
		fMaskUndo))
		{
		// if the undo is going to add the mask, we need to redraw the mask
		if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) )
			{
			if (GetMaskUpdateRect(YES, NO, &rTemp))
				AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp);
			}
		else
			// just redraw the undo area for the mask
			AstralUnionRect(&rUndoMask, &rUndoMask, &lpMask->Pixmap.UndoRect);
		}

	// Setup rectangle for undoing deletion of objects
	// Handled specially so that moved objects will still undo
	// and redo properly
	if (fEditUndo)
		{
		if (lpObject == lpBase &&
			lpObject->DataUndoType & UT_DELETEOBJECTS)
			{
			lpNext = lpObject;
			while (lpNext = GetNextObject(lpNext, YES, NO, YES))
				{
				if (lpNext->fDeleted || lpNext->fUndoDeleted)
					AstralUnionRect(&rUndo, &rUndo, &lpNext->rObject);
				}
			fSetupMiniViews = YES;
			}
		if (lpObject->DataUndoType & UT_COLORMAP)
			fColorMapChanged = YES;

		if (lpObject->Pixmap.fNewFrame)
			{
			/* if new frame, cause window to be redisplayed */
			if (lpObject == lpBase)
				fNewSize = YES;
			else
				{
				if (!fNewSize)
					{
					AstralUnionRect(&rUndo, &rUndo, &lpObject->rObject);
					AstralUnionRect(&rUndo, &rUndo, &lpObject->rUndoObject);
					}
				}
			}
		else
			{
			AstralSetRectEmpty(&rTemp);
			if (fUndoData)
				AstralUnionRect(&rTemp, &rTemp, &lpObject->Pixmap.UndoRect);
			if (fUndoAlpha)
				AstralUnionRect(&rTemp, &rTemp,
						&lpObject->lpAlpha->Pixmap.UndoRect);
			if (rTemp.right >= rTemp.left)
				{
				if (!fNewSize)
					{
					OffsetRect(&rTemp, lpObject->rObject.left,
							lpObject->rObject.top);
					AstralUnionRect(&rUndo, &rUndo, &rTemp);
					}
				}
			if( lpObject->DataUndoType & UT_OBJECTRECT )
				{
				AstralUnionRect( &rUndo, &rUndo,	&lpObject->rObject );
				AstralUnionRect( &rUndo, &rUndo,	&lpObject->rUndoObject );
				}
			}
		}
	}

// now redisplay whatever changes are necessary for the undo
if (fColorMapChanged)
	{
	ImgColorMapChanged(this);
	*lpUpdateType |= UT_DATATYPE;
	}

if (fNewSize)
	{
	*lpUpdateType |= UT_DATATYPE;
	if (lpBase->Pixmap.UndoFrame)
		{
		if ((FrameXSize(lpBase->Pixmap.UndoFrame) ==
			FrameXSize(lpBase->Pixmap.EditFrame)) &&
			(FrameYSize(lpBase->Pixmap.UndoFrame) ==
			FrameYSize(lpBase->Pixmap.EditFrame)))
			fNewSize = NO;
		}
	if (fNewSize)
		*lpUpdateType |= UT_SIZE;
	else
		{
		int dx, dy;

		GetInfo(&dx, &dy, NULL, NULL);
		SetRect(lpUpdateRect, 0, 0, dx-1, dy-1);
		}
	}
else
	{
	if (!AstralIsRectEmpty(lpUpdateRect))
		*lpUpdateType |= UT_ACTIVEAREA;
	if (rUndoMask.right >= rUndoMask.left)
		{
		*lpUpdateType |= UT_ACTIVEAREA;
		AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndoMask);
		}
	if (rUndo.right >= rUndo.left)
		{
		*lpUpdateType |= UT_AREA;
		AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndo);
		}
	}
}
Exemplo n.º 6
0
//************************************************************************
LOCAL STATUS_CODE ApplyCalibration(
	LPIMAGE		lpImage,
	ITEMID      dirty,
	LPSTR       lpScanMap,
	LPSTR       lpPrintMap,
	LPRECT		lpUpdateRect,
	LPUPDATE_TYPE lpUpdateType)
//************************************************************************
{
	FNAME  szFileName;
	ENGINE Engine;
	LPCALMAPS lpMaps;
	BOOL fScanMap, fPrintMap;
	FRMTYPEINFO TypeInfo;
	LPCOLORMAP lpColorMap;
	STATUS_CODE StatusCode;
	int i;
	
	ASSERT(lpImage);

	AstralSetRectEmpty(lpUpdateRect);
	*lpUpdateType = UT_NONE;

	ImgGetTypeInfo(lpImage, &TypeInfo);
	lpMaps = (LPCALMAPS)Alloc(sizeof(CALMAPS));
	if (!lpMaps)
	{
		Message(IDS_EMEMALLOC);
		return(SC_MEMERROR);
	}
	for (i = 0; i < CALSCAN_MAPS; ++i)
		ResetMap( &lpMaps->ScanMap[i], CALPOINTS, NO );

	if (fScanMap = (lstrlen(lpScanMap) != 0))
	{
		if ( LookupExtFileN( lpScanMap, szFileName, IDN_SCANMAP, NO ) )
		{
			// Remember that the maps load in XRGB order
			if (!LoadMap( 	&lpMaps->ScanMap[CALSCAN_GRAY],
							&lpMaps->ScanMap[CALSCAN_RED],
							&lpMaps->ScanMap[CALSCAN_GREEN],
							&lpMaps->ScanMap[CALSCAN_BLUE],
							szFileName ))
			{
				FreeUp(lpMaps);
				return(SC_READERROR);
			}
			if (TypeInfo.DataType == FDT_CMYKCOLOR)
			{
				// make maps work on cmyk
				for (i = 0; i < CALSCAN_MAPS; ++i)
					ReverseMap(&lpMaps->ScanMap[i], FALSE);
			}
		}
		else
		{
			fScanMap = NO;
		}
	}

	for (i = 0; i < CAL_MAPS; ++i)
		ResetMap( &lpMaps->PrintMap[i], CALPOINTS, NO );
	if (fPrintMap = (lstrlen(lpPrintMap) != 0))
	{
		if ( LookupExtFileN( lpPrintMap, szFileName, IDN_CALMAP, NO ) )
		{
			// Remember that the maps load in MCMYK order
			if (!LoadCalMap(	&lpMaps->PrintMap[CAL_MASTER],
								&lpMaps->PrintMap[CAL_CYAN],
								&lpMaps->PrintMap[CAL_MAGENTA],
								&lpMaps->PrintMap[CAL_YELLOW],
								&lpMaps->PrintMap[CAL_BLACK],
								szFileName ))
			{
				FreeUp(lpMaps);
				return(SC_READERROR);
			}
			if (TypeInfo.DataType != FDT_CMYKCOLOR)
			{
				// make maps work on rgb
				for (i = 0; i < CAL_MAPS; ++i)
					ReverseMap(&lpMaps->PrintMap[i], FALSE);
			}
		}
		else
		{
			fPrintMap = NO;
			lpPrintMap = NULL;
		}
	}

	if (!fScanMap && !fPrintMap)
	{
		FreeUp(lpMaps);
		return(SC_SUCCESS); // user selected no maps??? 
	}

	switch (TypeInfo.DataType)
	{
		case FDT_LINEART:
		case FDT_GRAYSCALE:
			MakeFloatMap(&lpMaps->ScanMap[CALSCAN_GRAY], lpMaps->CalPnts);
			MakeFloatMap(&lpMaps->PrintMap[CAL_BLACK], lpMaps->TmpPnts);
			MapCombine(lpMaps->CalPnts, lpMaps->TmpPnts);
			MapCreateLut(lpMaps->CalPnts, lpMaps->Lut[0]);
		break;

		case FDT_CMYKCOLOR:
			for (i = 0; i < 4; ++i)
			{
				if (i == 3) // black
					MakeFloatMap(&lpMaps->ScanMap[CALSCAN_GRAY], lpMaps->CalPnts);
				else
					MakeFloatMap(&lpMaps->ScanMap[CALSCAN_RED+i], lpMaps->CalPnts);
				MakeFloatMap(&lpMaps->PrintMap[CAL_MASTER], lpMaps->TmpPnts);
				MapCombine(lpMaps->CalPnts, lpMaps->TmpPnts);
				MakeFloatMap(&lpMaps->PrintMap[CAL_CYAN+i], lpMaps->TmpPnts);
				MapCombine(lpMaps->CalPnts, lpMaps->TmpPnts);
				MapCreateLut(lpMaps->CalPnts, lpMaps->Lut[i]);
			}
		break;

		default:
		case FDT_RGBCOLOR:
		case FDT_PALETTECOLOR:
			for (i = 0; i < 3; ++i)
			{
				MakeFloatMap(&lpMaps->ScanMap[CALSCAN_RED+i], lpMaps->CalPnts);
				MakeFloatMap(&lpMaps->PrintMap[CAL_MASTER], lpMaps->TmpPnts);
				MapCombine(lpMaps->CalPnts, lpMaps->TmpPnts);
				MakeFloatMap(&lpMaps->PrintMap[CAL_CYAN+i], lpMaps->TmpPnts);
				MapCombine(lpMaps->CalPnts, lpMaps->TmpPnts);
				MapCreateLut(lpMaps->CalPnts, lpMaps->Lut[i]);
			}
		break;
	}


	ImgGetTypeInfo(lpImage, &TypeInfo);
	if (TypeInfo.DataType == FDT_PALETTECOLOR)
	{
		lpColorMap = FrameCopyColorMap(TypeInfo.ColorMap);
		if (!lpColorMap)
		{
			Message(IDS_EMEMALLOC);
			return(SC_MEMERROR);
		}
		LineCalMapProc(0, 0, lpColorMap->NumEntries-1,
							(LPTR)lpColorMap->RGBData,
							(LPTR)lpColorMap->RGBData,
							3,
							lpMaps);
		StatusCode = ApplyColorMap(lpImage, lpColorMap, FALSE, DT_NONE, dirty);
		FrameDestroyColorMap(lpColorMap);
		if (StatusCode == SC_SUCCESS)
			*lpUpdateType = UT_DATATYPE;
	}
	else
	{
		SetEngineDef(&Engine);
		Engine.lpDataProc = (LPDATAPROC)LineCalMapProc;

		Engine.lpParam = lpMaps;
		StatusCode = LineEngineSelObj(lpImage, &Engine, dirty);
		if (!AstralIsRectEmpty(&Engine.rUpdate))
		{
			*lpUpdateRect = Engine.rUpdate;
			*lpUpdateType = UT_AREA;
		}
	}
	FreeUp(lpMaps);
	return(StatusCode);
}
Exemplo n.º 7
0
BOOL GradientImage( LPIMAGE lpImage, LPGRADIENT_PARMS lpParms)
{
	LPFRAME lpFrame;
	RECT rMask;
	LPINT lpD;
	FRMTYPEINFO TypeInfo;
	int dx, dy, iCount;
	int index, prev, next, pi, ni;
	long ldx, ldy, x, y, xs, xe, ys, ye, asqrd, bsqrd, r;
	LPDATAPROC lpVignetteProc;
	ENGINE Engine;
	BOOL   DoHSL;
	GRADIENT_DATA data;
	int res;

   FRMDATATYPE type;
	ImgGetInfo(lpImage, NULL, NULL, NULL, &type);
	if (type == FDT_LINEART)
		return(FALSE);
	if (!(lpFrame = ImgGetBaseEditFrame(lpImage)))
		return(FALSE);
	res = FrameResolution(lpFrame);
	data.x1 = lpParms->x1;
	data.y1 = lpParms->y1;
	data.x2 = lpParms->x2;
	data.y2 = lpParms->y2;
	ResConvertUL(lpParms->iBaseRes, res, &data.x1, &data.y1);
	ResConvertLR(lpParms->iBaseRes, res, &data.x2, &data.y2);
	dx = data.x2 - data.x1;
	dy = data.y2 - data.y1;
	data.SoftTransition = lpParms->SoftTransition;
	data.lpPaletteLUT = NULL;

	if (lpParms->Gradient == IDC_VIGLINEAR || lpParms->Gradient == IDC_VIGRADIAL)
	{
		if (abs(dx) <= 3 && abs(dy) <= 3)
			return(FALSE);
	}
	else
	{
		if (abs(dx) <= 3 || abs(dy) <= 3)
			return(FALSE);
	}

	data.xc = (data.x1 + data.x2) / 2;
	data.yc = (data.y1 + data.y2) / 2;

	if ( (data.nRepetitions = lpParms->RepeatCount) <= 0 )
		data.nRepetitions = 1;

	FrameGetTypeInfo(lpFrame, &TypeInfo);

	DoHSL = (lpParms->VigColorModel+IDC_FIRST_MODEL) != IDC_MODEL_RGB &&
				(TypeInfo.DataType > FDT_GRAYSCALE);

	switch (lpParms->Gradient)
	{
		case IDC_VIGLINEAR:
			data.D = lsqrt(((long)dx*(long)dx)+((long)dy*(long)dy));
			data.sine = FGET(-dy, data.D);
			data.cosine = FGET(dx, data.D);
			data.xr = WHOLE(( rotx(data.x2, data.y2, data.x1, data.y1,
            data.cosine, data.sine) ));
			lpVignetteProc = (LPDATAPROC)linear_vignette_proc;
		break;

		case IDC_VIGRADIAL:
			data.D = lsqrt(((long)dx*(long)dx)+((long)dy*(long)dy));
			lpVignetteProc = (LPDATAPROC)radial_vignette_proc;
		break;

		case IDC_VIGCIRCLE:
			data.x1 = data.xc;
			data.y1 = data.yc;
			data.y2 = data.yc;
			dx = data.x2 - data.x1;
			dy = data.y2 - data.y1;
			if (!dx && !dy)
				return(FALSE);
			data.D = lsqrt(((long)dx*(long)dx)+((long)dy*(long)dy));
			lpVignetteProc = (LPDATAPROC)radial_vignette_proc;
		break;

		case IDC_VIGSQUARE:
		case IDC_VIGRECTANGLE:
			data.ymin = min(data.y1, data.y2);
			data.ymax = max(data.y1, data.y2);
			data.xmin = min(data.x1, data.x2);
			data.xmax = max(data.x1, data.x2);

			ldx = data.xmin-data.xc;		// upper left
			ldy = data.ymin-data.yc;
			data.m1 = (256L * ldy) / ldx;
			data.b1 = data.ymin - ((data.m1 * data.xmin)/256L);
			data.D1 = lsqrt((ldx*ldx)+(ldy*ldy));

			ldx = data.xmax-data.xc;		// upper right
			ldy = data.ymin-data.yc;
			data.m2 = (256L * ldy) / ldx;
			data.b2 = data.ymin - ((data.m2 * data.xmax)/256L);
			data.D2 = lsqrt((ldx*ldx)+(ldy*ldy));

			ldx = data.xmax-data.xc;		// lower right
			ldy = data.ymax-data.yc;
			data.m3 = (256L * ldy) / ldx;
			data.b3 = data.ymax - ((data.m3 * data.xmax)/256L);
			data.D3 = lsqrt((ldx*ldx)+(ldy*ldy));

			ldx = data.xmin-data.xc;		// lower left
			ldy = data.ymax-data.yc;
			data.m4 = (256L * ldy) / ldx;
			data.b4 = data.ymax - ((data.m4 * data.xmin)/256L);
			data.D4 = lsqrt((ldx*ldx)+(ldy*ldy));

			lpVignetteProc = (LPDATAPROC)rectangle_vignette_proc;
		break;

		case IDC_VIGELLIPSE:
			if ( !(data.lpD = (LPINT)Alloc((long)sizeof(int)*(TSIZE+1))) )
			{
				Message(IDS_EMEMALLOC);
				return(FALSE);
			}
			iCount = TSIZE+1;
			lpD = data.lpD;
			while (--iCount >= 0)
				*lpD++ = -1;				
			data.ymin = min(data.y1, data.y2);
			data.ymax = max(data.y1, data.y2);
			data.xmin = min(data.x1, data.x2);
			data.xmax = max(data.x1, data.x2);
			data.ea = dx/2;
			data.eb = dy/2;
			if (!data.ea || !data.eb)
			{
				FreeUp((LPTR)data.lpD);
				return(FALSE);
			}
			asqrd = data.ea*data.ea;
			bsqrd = data.eb*data.eb;

			// fill in a table with radius information for the
			// ellipse.  The radius for a given point would be
			// starting from the center of the ellipse, going 
			// through to point, and where it intersects the 
			// edge of the ellipse.  We need the radius for
			// the D value used in the ellipse_proc, which is
			// the maximum distance used for determining how to
			// calculate the gradient, which is d/D.  d is the 
			// distance of the point from the center, D is extracted
			// from the table built below.  The index of the table is
			// formed from the ratio of sides of the triangle formed.
			// This is like looking up the angle to see where the
			// point would intersect the circle.  But we calculate
			// the radii ahead of time to speed things up.
			if (data.ea > data.eb)	// step in x
			{
				xs = data.xc - data.xc;
				xe = data.xmax - data.xc;
				for (x = xs; x <= xe; ++x)
				{
					y = ((data.eb*(long)lsqrt(asqrd - (x*x)))+(data.ea/2))/data.ea;
					r = (x*x)+(y*y);
					if (r <= 0)
						r = 1;
					index = ((x * x * (long)TSIZE)+(r/2)) / r;
					index = bound(abs(index), 0, TSIZE);
					data.lpD[index] = lsqrt(r);
				}
			}
			else		// step in y
			{
				ys = data.yc - data.yc;
				ye = data.ymax - data.yc;
				for (y = ys; y <= ye; ++y)
				{
					x = ((data.ea*(long)lsqrt(bsqrd - (y*y)))+(data.eb/2))/data.eb;
					r = (x*x)+(y*y);
					if (r <= 0)
						r = 1;
					index = ((y * y * (long)TSIZE)+(r/2)) / r;
					index = bound(abs(index), 0, TSIZE);
					data.lpD[index] = lsqrt(r);
				}
			}
			// find the first valid entry in our table
			for (index = 0; index <= TSIZE && data.lpD[index] < 0; ++index)
				;

			// see if we have any entries
			if (index > TSIZE)
			{
				FreeUp((LPTR)data.lpD);
				return(FALSE);
			}

			// fill in all entries before first with value of first
			while (--index >= 0)
				data.lpD[index] = data.lpD[index+1];

			// find last valid entry in table
			for (index = TSIZE; index >= 0 && data.lpD[index] < 0; --index)
				;

			// see if we have any entries
			if (index < 0)
			{
				FreeUp((LPTR)data.lpD);
				return(FALSE);
			}

			// fill in all entries after last with value of last
			while (++index <= TSIZE)
				data.lpD[index] = data.lpD[index-1];

			// interpolate values of all empty cells
			for (index = 0; index <= TSIZE; ++index)
			{
				if (data.lpD[index] < 0)
				{
					pi = index - 1;
					prev = data.lpD[pi];
					ni = index;
					while (data.lpD[ni] < 0)
						++ni;
					next = data.lpD[ni];
					// remember here that (index-pi) == 1
					data.lpD[index] = prev + ((next-prev)/(ni-pi));
				}
			}
			lpVignetteProc = (LPDATAPROC)ellipse_vignette_proc;
		break;

		default:
			return(FALSE);
		break;
	}

	switch(TypeInfo.DataType)
	{
		case FDT_LINEART :
		case FDT_GRAYSCALE :
			data.lpProcessProc = (LPVIGPROC)ProcessVignette8;
		break;

		case FDT_PALETTECOLOR:
			data.lpProcessProc = (LPVIGPROC)ProcessVignette8P;
			data.lpPaletteLUT = CreatePaletteLut15(TypeInfo.ColorMap->RGBData,
					TypeInfo.ColorMap->NumEntries, NULL, NULL);
		break;

		case FDT_RGBCOLOR :
			data.lpProcessProc = (LPVIGPROC)ProcessVignette24;
		break;

		case FDT_CMYKCOLOR :
			data.lpProcessProc = (LPVIGPROC)ProcessVignette32;
		break;
	}

	data.lpMidpointTable = BuildMidPointTable(
							DoHSL,
							TypeInfo.DataType,
							lpParms->Midpoint,
							&lpParms->StartColor,
							&lpParms->EndColor,
							&data );

	ImgGetMaskRect( lpImage, &rMask );
	data.lplD = (LPLONG)Alloc((long)sizeof(long)*(long)RectWidth(&rMask));
	data.lpld = (LPLONG)Alloc((long)sizeof(long)*(long)RectWidth(&rMask));

	if (!data.lpld || !data.lplD || !data.lpMidpointTable ||
		(TypeInfo.DataType == FDT_PALETTECOLOR && !data.lpPaletteLUT))
	{
		if (lpParms->Gradient == IDC_VIGELLIPSE)
			FreeUp((LPTR)data.lpD);
		if (data.lplD)
			FreeUp((LPTR)data.lplD);
		if (data.lpld)
			FreeUp((LPTR)data.lpld);
		if (data.lpMidpointTable)
			FreeUp((LPTR)data.lpMidpointTable);
		if (data.lpPaletteLUT)
			FreeUp(data.lpPaletteLUT);
		return(FALSE);
	}

	SetEngineDraw(&Engine,lpVignetteProc,lpParms->VigOpacity,lpParms->VigMergeMode);
	Engine.lpParam = &data;
	Engine.fThread = NO;
	lpParms->Common.StatusCode = LineEngineSelObj(lpImage,&Engine,lpParms->Common.idDirty);
	if (!AstralIsRectEmpty(&Engine.rUpdate))
	{
		lpParms->Common.UpdateType = UT_AREA;
		lpParms->Common.rUpdateArea = Engine.rUpdate;
	}

	FreeUp((LPTR)data.lpld);
	FreeUp((LPTR)data.lplD);
	FreeUp((LPTR)data.lpMidpointTable);
	if (data.lpPaletteLUT)
		FreeUp(data.lpPaletteLUT);

	if (lpParms->Gradient == IDC_VIGELLIPSE)
		FreeUp((LPTR)data.lpD);
	return(lpParms->Common.StatusCode == SC_SUCCESS);
}