LOCAL LPFRAME ConvertFrame(LPFRAME lpSrcFrame, FRMTYPEINFO OutTypeInfo, CFrameTypeConvert *pTypeConvert) /***********************************************************************/ { int y, Xsize, Ysize; LPFRAME lpDstFrame; FRMTYPEINFO InTypeInfo; LPTR lpSrc, lpDst; CFrameTypeConvert TypeConvert; Xsize = FrameXSize(lpSrcFrame); Ysize = FrameYSize(lpSrcFrame); FrameGetTypeInfo(lpSrcFrame, &InTypeInfo); if (!pTypeConvert) { if (!TypeConvert.Init(InTypeInfo, OutTypeInfo, Xsize)) { Message(IDS_EMEMALLOC); return(NULL); } pTypeConvert = &TypeConvert; } lpDstFrame = FrameOpen(OutTypeInfo, Xsize, Ysize, FrameResolution(lpSrcFrame)); if (!lpDstFrame) { FrameError(IDS_EPROCESSOPEN); return(NULL); } ProgressBegin(1, 0); for (y = 0; y < Ysize; ++y) { if (AstralClockCursor(y, Ysize, YES)) { FrameClose(lpDstFrame); goto ExitError; } if (!(lpSrc = FramePointerRaw(lpSrcFrame, 0, y, NO))) continue; if (!(lpDst = FramePointerRaw(lpDstFrame, 0, y, YES))) continue; pTypeConvert->ConvertData(lpSrc, lpDst, y, Xsize); } ProgressEnd(); return(lpDstFrame); ExitError: ProgressEnd(); return(NULL); }
void FramePutRGB( LPFRAME lpFrame, LPRGB lpSrcRGB, LPTR lpDst, int iPixelCount) { CFrameTypeConvert TypeConvert; FRMTYPEINFO SrcTypeInfo, DstTypeInfo; if (!lpFrame) return; FrameSetTypeInfo(&SrcTypeInfo, FDT_RGBCOLOR); FrameGetTypeInfo(lpFrame, &DstTypeInfo); if (!TypeConvert.Init(SrcTypeInfo, DstTypeInfo, iPixelCount, DT_NONE)) return; TypeConvert.ConvertData((LPTR)lpSrcRGB, lpDst, 0, iPixelCount); }
// Gets the current mask if any. // If no mask exists then create one using fOn and fNoUndo. // bCreated is TRUE if a new mask was created. LPMASK CImage::GetMaskEx(BOOL fOn, BOOL fNoUndo, LPINT bCreated, LPRECT lpUpdateRect) { LPMASK lpMask; LPFRAME lpFrame; FRMTYPEINFO TypeInfo; FRMDATATYPE FrameType = FDT_GRAYSCALE; AstralSetRectEmpty(lpUpdateRect); if (lpMask = GetMask()) { if (bCreated) *bCreated = FALSE; return(lpMask); } lpFrame = GetBaseEditFrame(); FrameGetTypeInfo(lpFrame, &TypeInfo); if (TypeInfo.DataType == FDT_LINEART && Mask.OneBitMask) FrameType = FDT_LINEART; if (!(lpMask = MaskCreate(NULL, FrameXSize(lpFrame), FrameYSize(lpFrame), fOn, fNoUndo, FrameType))) { Message( IDS_EMEMALLOC ); return(NULL); } // sync up the resolution of the image data and the mask // don't ever rely on the mask's resolution being correct // cause other size can change the image data resolution // without changing the mask's resolution. Also, there are // other places the mask gets created without syncing up // the resolution. I am doing it here so we can begin // to track it correctly (Ted) FrameSetResolution(AlphaGetEditFrame(lpMask), FrameResolution(lpFrame)); if (bCreated) *bCreated = TRUE; if (!Control.UseMaskAndObjects) GetObjectMarqueeRect(this, lpUpdateRect); SetMask(lpMask); return(lpMask); }
void ImgInitDisplay(LPIMAGE lpImage, BOOL fGeneratePaletteLUT) /***********************************************************************/ { LPTR lpPaletteLUT; RGBS RGBmap[256]; LPRGB lpRGBmap; int nColors; FRMTYPEINFO TypeInfo, DstTypeInfo = ColorManager.Monitor.dst; LPOBJECT lpObject; lpObject = lpImage->GetDisplayObject(); if (!lpObject) return; FrameGetTypeInfo(ObjGetEditFrame(lpObject), &TypeInfo); if ( lpBltScreen->BitMapInfo.bmiHeader.biBitCount == 8 && !lpImage->lpPaletteLUT) { ProgressBegin(1, PROGRESS_ID(IDS_UNDOSETUPDISPLAY)); if (TypeInfo.DataType == FDT_PALETTECOLOR) lpPaletteLUT = Alloc(32768L); else lpPaletteLUT = NULL; if (lpPaletteLUT) { if (TypeInfo.ColorMap->NumEntries > MAX8BITCOLORS) { nColors = MAX8BITCOLORS; lpRGBmap = RGBmap; if (!ReducePalette(TypeInfo.ColorMap->RGBData, TypeInfo.ColorMap->NumEntries, lpRGBmap, nColors)) { FreeUp(lpPaletteLUT); lpPaletteLUT = NULL; } } else { lpRGBmap = TypeInfo.ColorMap->RGBData; nColors = TypeInfo.ColorMap->NumEntries; } } if (lpPaletteLUT) { if (fGeneratePaletteLUT) CreatePaletteLut15(lpRGBmap, nColors, lpPaletteLUT, AstralClockCursor); lpImage->lpPaletteLUT = lpPaletteLUT; lpImage->PaletteType = PT_CUSTOMPALETTE; lpImage->hPal = CreateLogicalPalette(lpRGBmap, nColors); GetObject(lpImage->hPal, sizeof(nColors), (void *)&nColors); lpImage->nPaletteEntries = GetPaletteEntries(lpImage->hPal, 0, nColors, lpImage->Palette); } else { if ( FrameType(ImgGetBaseEditFrame(lpImage)) <= FDT_GRAYSCALE) { lpImage->hPal = lpBltScreen->hGrayPal; lpImage->nPaletteEntries = lpBltScreen->nGrayEntries; lpImage->PaletteType = lpBltScreen->GrayPaletteType; lpImage->lpPaletteLUT = lpBltScreen->lpGrayPaletteLUT; copy((LPTR)lpBltScreen->GrayPalette, (LPTR)lpImage->Palette, sizeof(lpImage->Palette)); } else { lpImage->hPal = lpBltScreen->hColorPal; lpImage->nPaletteEntries = lpBltScreen->nColorEntries; lpImage->PaletteType = lpBltScreen->ColorPaletteType; lpImage->lpPaletteLUT = lpBltScreen->lpColorPaletteLUT; copy((LPTR)lpBltScreen->ColorPalette, (LPTR)lpImage->Palette, sizeof(lpImage->Palette)); } } ProgressEnd(); } if (lpImage->m_cmsXform) { if( Control.CMSEnabled && lpKCMSFreeProc ) { if (lpImage->PtInfo.toRCS != TypeInfo.ptInfo.toRCS && lpImage->PtInfo.frRCS != TypeInfo.ptInfo.frRCS ) { ( lpKCMSFreeProc )( lpImage->m_cmsXform ); lpImage->m_cmsXform = NULL; } } else lpImage->m_cmsXform = NULL; } if( Control.CMSEnabled && IsSrcPTSelected( &TypeInfo.ptInfo ) && IsDstPTSelected( &DstTypeInfo.ptInfo ) && lpKCMSCnctProc ) { lpImage->m_bDoCmsGamma = YES; if (!lpImage->m_cmsXform) { if( ( !FrameTypeInfoEqual( TypeInfo, DstTypeInfo ) ) && ConvertCRCtoUID( &TypeInfo, &DstTypeInfo ) ) { // save for later check to avoid a monitor reconnect. lpImage->PtInfo = TypeInfo.ptInfo; lpImage->m_cmsXform = ( *lpKCMSCnctProc )( &TypeInfo, &DstTypeInfo ); } else lpImage->m_cmsXform = NULL; } } else lpImage->m_cmsXform = NULL; }
BOOL ObjGetLine(LPOBJECT lpObject, int x, int y, int dx, LPTR lpOut) /************************************************************************/ { LPALPHA lpAlpha; LPTR lp; LPPROCESSPROC lpProcessProc; RECT rLine, rSect; int nPixels, ox, oy, depth; FRMTYPEINFO TypeInfo; FRMDATATYPE DataType; long lOffset; LPFRAME lpFrame; // fill buffer with base image object // use depth of base image object lpFrame = ObjGetEditFrame(lpObject); FrameGetTypeInfo(lpFrame, &TypeInfo); DataType = TypeInfo.DataType; depth = FrameDepth(lpFrame); if (TypeInfo.DataType == FDT_LINEART) { depth = 1; TypeInfo.DataType = FDT_GRAYSCALE; } if (!ObjGetLineAlloc(dx, depth)) { //Message(IDS_EMEMALLOC); return(FALSE); } if (!FrameRead(lpFrame, x, y, dx, lpOut, dx)) return(FALSE); // setup rect for this line for intersect check rLine.left = x; rLine.right = x + dx - 1; rLine.top = rLine.bottom = y; // start with first object on top of base image while(lpObject = lpObject->lpNext) { // if object cannot be rendered through raster means if (lpObject->fDeleted || !AstralIntersectRect(&rSect, &lpObject->rObject, &rLine)) continue; // get merge proc for this object lpProcessProc = GetProcessProc(lpObject->MergeMode, DataType); ox = rSect.left-lpObject->rObject.left; oy = y-lpObject->rObject.top; nPixels = (rSect.right - rSect.left + 1); lOffset = (long)(rSect.left - rLine.left) * depth; lp = FramePointer(ObjGetEditFrame(lpObject), ox, oy, NO, nPixels); if (lp) { if (lpAlpha = ObjGetAlpha(lpObject)) { MaskLoad(lpAlpha, ox, oy, nPixels, lpGLMaskBuf); if (lpObject->Opacity != 255) ScaleData8(lpGLMaskBuf, nPixels, lpObject->Opacity); } else set(lpGLMaskBuf, nPixels, lpObject->Opacity); (*lpProcessProc)(lpOut+lOffset, lp, lpGLMaskBuf, nPixels); } } return(TRUE); }
BOOL ConvertImage(LPIMAGE lpImage, LPCONVERT_PARMS lpParms) /***********************************************************************/ { BOOL fRet = FALSE; LPFRAME lpDstFrame, lpBaseFrame; LPOBJECT lpBase, lpObject; BOOL fError, fOptimize, fProgressSet; INTERNAL_DATA data; int inDepth, iMaxWidth, nColors, i; LPCOLORMAP lpColorMap; LPRGB lpRGB; FRMTYPEINFO InTypeInfo, OutTypeInfo; CFrameTypeConvert TypeConvert; DITHER_TYPE DitherType = DT_DEFAULT; if (ImgInMaskEditMode(lpImage)) return(TRUE); lpColorMap = NULL; lpBase = ImgGetBase(lpImage); lpBaseFrame = ObjGetEditFrame(lpBase); inDepth = FrameDepth(lpBaseFrame); OutTypeInfo = lpParms->cmsInfo.dst; FrameGetTypeInfo(lpBaseFrame, &InTypeInfo); // are we try to convert to a color managed image? if (Control.CMSEnabled && IsDstPTSelected(&OutTypeInfo.ptInfo)) { // see if our image already has a color managed source if (!IsSrcPTSelected(&InTypeInfo.ptInfo)) { // nope, see if the source passed in is valid for this image if (IsSrcPTSelected(&lpParms->cmsInfo.src.ptInfo) && (lpParms->cmsInfo.src.DataType == InTypeInfo.DataType)) { InTypeInfo = lpParms->cmsInfo.src; } // go get a source from the user else { CMSINFO CmsInfo2; if( CmsGetSrcPTType( &InTypeInfo, &CmsInfo2) ) InTypeInfo = CmsInfo2.src; } } } else FrameSetTypeInfo(&InTypeInfo, InTypeInfo.DataType, InTypeInfo.ColorMap); // no conversion necessary if (FrameTypeInfoEqual(InTypeInfo, OutTypeInfo)) return(TRUE); DitherType = lpParms->DitherType; fOptimize = lpParms->ConvertType == CT_OPTIMIZED; fProgressSet = FALSE; if ( OutTypeInfo.DataType == FDT_PALETTECOLOR/* && inDepth >= 3 */) { if (lpParms->ConvertType == CT_CUSTOM) { FNAME szFileName; if ( !LookupExtFileN( lpParms->szPalette, szFileName, IDN_PALETTE, NO ) ) return(FALSE); if (!(lpColorMap = Palette_ReadColorMap(szFileName))) return(FALSE); } else { // allocate a map to carry around with image lpColorMap = FrameCreateColorMap(); if (!lpColorMap) { Message(IDS_EMEMALLOC); goto MemError; } lpColorMap->NumEntries = lpParms->iLevels; if (InTypeInfo.DataType == FDT_GRAYSCALE && lpColorMap->NumEntries == 256 && fOptimize) { DitherType = DT_NONE; lpRGB = lpColorMap->RGBData; for (i = 0; i < lpColorMap->NumEntries; ++i) { lpRGB->red = lpRGB->green = lpRGB->blue = i; ++lpRGB; } } else { // 1. CreateOptimizedPalette phase - only if fOptimize // 2. Mapping phase ProgressBegin(fOptimize ? 2 : 1, lpParms->Common.idDirty-IDS_UNDOFIRST+IDS_PROGFIRST); fProgressSet = TRUE; if (fOptimize) ProgressBegin(1, 0); if (!CreateOptimizedPalette(lpBase, ObjGetEditFrame(lpBase), lpColorMap->RGBData, &lpColorMap->NumEntries, fOptimize, fOptimize ? AstralClockCursor : NULL)) { if (fOptimize) ProgressEnd(); Message(IDS_EMEMALLOC); goto ExitFalse; } if (fOptimize) ProgressEnd(); } } if (lpColorMap->NumEntries <= 16) lpColorMap->NumEntries = 16; else lpColorMap->NumEntries = 256; FrameSetTypeInfo(&OutTypeInfo, FDT_PALETTECOLOR, lpColorMap); } if (!fProgressSet) ProgressBegin(1, lpParms->Common.idDirty-IDS_UNDOFIRST+IDS_PROGFIRST); fProgressSet = TRUE; iMaxWidth = 0; lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { if (RectWidth(&lpObject->rObject) > iMaxWidth) iMaxWidth = RectWidth(&lpObject->rObject); } if (!TypeConvert.Init(InTypeInfo, OutTypeInfo, iMaxWidth, DitherType)) { Message(IDS_EMEMALLOC); goto ExitFalse; } if (ImgMultipleObjects(lpImage)) { ProgressBegin(ImgCountObjects(lpImage), 0); if ( !ImgEditInit(lpImage, ET_ALLOBJECTS, UT_NEWDATA|UT_COLORMAP, lpBase) ) goto ExitFalse; fError = NO; lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { lpDstFrame = ConvertFrame(ObjGetEditFrame(lpObject), OutTypeInfo, &TypeConvert); if (!lpDstFrame) { fError = YES; break; } ImgEditedObjectFrame( lpImage, lpObject, lpParms->Common.idDirty, NULL, lpDstFrame, NULL); } if (fError) { lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { if (lpObject->Pixmap.UndoFrame) { lpDstFrame = lpObject->Pixmap.EditFrame; lpObject->Pixmap.EditFrame = lpObject->Pixmap.UndoFrame; lpObject->Pixmap.UndoFrame = NULL; FrameClose(lpDstFrame); } } } ProgressEnd(); } else { if ( !ImgEditInit(lpImage, ET_OBJECT, UT_NEWDATA|UT_COLORMAP, lpBase) ) goto ExitFalse; ProgressBegin(1, 0); lpDstFrame = ConvertFrame(lpBaseFrame, OutTypeInfo, &TypeConvert); ProgressEnd(); if (!lpDstFrame) goto ExitFalse; /* Setup the new image and bring up the new image window */ ImgEditedObjectFrame( lpImage, lpBase, lpParms->Common.idDirty, NULL, lpDstFrame, NULL); } switch (lpParms->cmsInfo.dst.DataType) { case FDT_LINEART: lpImage->DataType = IDC_SAVELA; break; case FDT_GRAYSCALE: lpImage->DataType = IDC_SAVECT; break; case FDT_PALETTECOLOR: lpImage->DataType = IDC_SAVE8BITCOLOR; break; case FDT_RGBCOLOR: lpImage->DataType = IDC_SAVE24BITCOLOR; break; case FDT_CMYKCOLOR: lpImage->DataType = IDC_SAVE32BITCOLOR; break; } ImgColorMapChanged(lpImage); lpParms->Common.UpdateType = UT_DATATYPE; fRet = TRUE; ExitFalse: if (fProgressSet) ProgressEnd(); MemError: if (lpColorMap) FrameDestroyColorMap(lpColorMap); return(fRet); }
void CImage::GetTypeInfo(LPFRMTYPEINFO lpTypeInfo) { FrameGetTypeInfo(GetBaseEditFrame(), lpTypeInfo); }
static LPTR FrameToColorDIB( LPFRAME lpFrame, LPRECT lpRect ) { int y, bpl; LPTR lpSrc, lpDIBMem, lpConvertLine; HPTR hpDstLine; DWORD lCount, lImageSize, lInfoSize; int dx, dy; LPBITMAPINFO lpInfo; FRMTYPEINFO SrcTypeInfo, DstTypeInfo; CFrameTypeConvert TypeConvert; if ( !lpFrame ) return( NULL ); FrameGetTypeInfo(lpFrame, &SrcTypeInfo); FrameSetTypeInfo(&DstTypeInfo, FDT_RGBCOLOR); dx = (lpRect->right - lpRect->left) + 1; dy = (lpRect->bottom - lpRect->top) + 1; lInfoSize = sizeof(BITMAPINFOHEADER); bpl = dx * 3; // Always 24-bit color out bpl = 4 * ((bpl + 3) / 4); // DIB packing lImageSize = (long)bpl * dy; lCount = lInfoSize + lImageSize; // Allocate the memory to hold the DIB if ( !(lpDIBMem = Alloc( lCount )) ) { FrameSetError( ERR_MALLOC ); return( NULL ); } if ( !(lpConvertLine = Alloc( bpl )) ) { FreeUp(lpDIBMem); FrameSetError( ERR_MALLOC ); return( NULL ); } lpInfo = (LPBITMAPINFO)lpDIBMem; lpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpInfo->bmiHeader.biWidth = dx; lpInfo->bmiHeader.biHeight = dy; lpInfo->bmiHeader.biPlanes = 1; lpInfo->bmiHeader.biCompression = BI_RGB; lpInfo->bmiHeader.biBitCount = 24; lpInfo->bmiHeader.biSizeImage = lImageSize; lpInfo->bmiHeader.biXPelsPerMeter = (10000L * (long) FrameResolution(lpFrame)) / 254L; lpInfo->bmiHeader.biYPelsPerMeter = (10000L * (long) FrameResolution(lpFrame)) / 254L; lpInfo->bmiHeader.biClrUsed = 0; lpInfo->bmiHeader.biClrImportant = 0; hpDstLine = (HPTR)lpDIBMem; hpDstLine += lInfoSize; if (!TypeConvert.Init(SrcTypeInfo, DstTypeInfo, dx)) { FreeUp(lpDIBMem); FreeUp(lpConvertLine); FrameSetError( ERR_MALLOC ); return( NULL ); } // This goes backwards... for (y = lpRect->bottom; y >= lpRect->top; y--) { lpSrc = FramePointer(lpFrame, lpRect->left, y, NO); if (lpSrc) { TypeConvert.ConvertData(lpSrc, lpConvertLine, y, dx); swapBGR( lpConvertLine, lpConvertLine, dx); CopyToHuge(lpConvertLine, hpDstLine, bpl); } hpDstLine += bpl; } FreeUp(lpConvertLine); return( lpDIBMem ); }
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); }