home *** CD-ROM | disk | FTP | other *** search
- /*
-
- SampleFilt.c
-
- Sample Filter Effect for DiVA VideoShop
-
- 04/28/92 Ivçn Cavero Bela£nde
-
-
- */
-
- #include <Types.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <QDOffscreen.h>
- #include <Dialogs.h>
- #include <OSUtils.h>
- #include <Packages.h>
- #include <Errors.h>
- #include <ToolUtils.h>
- #include <SysEqu.h>
- #include <Math.h>
- #include <GestaltEqu.h>
- #include "DiVAFilter.h"
-
- /* Konstants */
-
- /* Shades of gray for 3-D objects */
- #define kLightGray 0xffff
- #define kMediumGray 0xdddd
- #define kDarkGray 0xaaaa
-
- /* Dialog konstants */
- #define dialogID 16001
- #define defaultItem 3
- #define intensityItem 5
- #define dividerLinesItem 7
- #define imageItem 9
- #define frameItem 10
- #define forwardItem 11
- #define backwardItem 12
-
- /* Type Definitions */
-
- typedef struct Params {
- short filterIntensity;
- Boolean backward; // defaults to false (end pixellated)
- FiltParamPtr filterParamBlock; // Ptr to paramblock for use of custom ditems.
- } Params, **ParamsHandle;
-
- /* Prototypes */
-
- FiltErr DoParameters (FiltParamPtr params);
-
- FiltErr DoProcessFrame (FiltParamPtr params, short currentStep, short totalSteps);
-
- void DoFilter (PixMapHandle src, GWorldPtr destGW, short current,
- short total, short intensity);
-
-
- pascal FiltErr FilterEntryPoint (short selector, FiltParamPtr params, long *data,
- short currentStep, short totalSteps)
- /* The entry point for the filter module. Conforms to */
- {
- #pragma unused(data)
- /* If first call, allocate and initialize our globals */
- switch (selector) {
- case FiltParameters:
- return (DoParameters (params));
- break;
- case FiltPrepare:
- case FiltStart:
- case FiltFinish:
- return (noErr);
- break;
- case FiltProcessFrame:
- return (DoProcessFrame (params,currentStep,totalSteps));
- break;
- default:
- return (-1);
- }
- }
-
- pascal Boolean DoTestAbort (ProcPtr codeAddress)
- /* Inline code to call the TestAbort function */
- = {0x205F, // move.l (a7)+,a0 pop procPtr from stack
- 0x4E90}; // jsr (a0) and call it
-
- Boolean TestAbort (FiltParamPtr params)
- {
- ProcPtr address;
-
- address = params->abortProc;
- return (DoTestAbort (address));
- }
-
- pascal void DoUpdateProgress (long done, long total, ProcPtr codeAddress)
- /* Inline code to call the UpdateProgress function */
- = {0x205F, // move.l (a7)+,a0 pop procPtr from stack
- 0x4E90}; // jsr (a0) and call it
-
- void UpdateProgress (FiltParamPtr params, long done, long total)
- {
- ProcPtr address;
-
- address = params->progressProc;
- DoUpdateProgress (done, total, address);
- }
-
- void CenterDialogBestDevice (DialogTHndl dt)
- /*
- Given a dialog template in dt, modify it so as to center the dialog on the
- best (deepest) device. Used to place options dialog (with image preview)
- in that device.
- */
- {
- short width;
- short height;
- GDHandle maxDevice;
- RgnHandle grayRgn = GetGrayRgn();
- Rect r = (**grayRgn).rgnBBox,dr;
-
- maxDevice = GetMaxDevice(&r);
- r = (**maxDevice).gdRect;
- width = r.right - r.left;
- height = r.bottom - r.top;
-
- dr = (**dt).boundsRect;
- OffsetRect (&dr, r.left-dr.left, r.top-dr.top);
- OffsetRect (&dr, (width - (dr.right-dr.left)) / 2,
- (height - (dr.bottom-dr.top) - GetMBarHeight()) / 3 + GetMBarHeight());
- (**dt).boundsRect = dr;
- }
-
- GDHandle GetWindowGDevice(WindowPtr w)
- /*
- Find the deepest gdevice the window intersects. Used for determining the depth
- of the screen we're drawing on (to look good on B/W displays).
- */
- {
- Rect r=w->portRect;
- GrafPtr oldPort;
- GDHandle theGD;
-
- GetPort (&oldPort);
- SetPort (w);
- LocalToGlobal((Point *)&r);
- LocalToGlobal((Point *)(&(r.bottom)));
- theGD = GetMaxDevice(&r);
- SetPort (oldPort);
- return (theGD);
- }
-
- pascal void DrawLines (DialogPtr theDialog, short itemNo)
- /*
- userItem drawing routine for dividing lines (with shadow)
- */
- {
- RGBColor oldColor,greyColor;
- short itemType;
- Handle me;
- Rect box;
-
- GetDItem(theDialog,itemNo,&itemType,&me,&box);
- GetForeColor(&oldColor);
- RGBForeColor((RGBColor*)RGBBlack);
- MoveTo(box.left,box.top);
- LineTo(box.right-2,box.top);
- MoveTo(box.left,box.top+3);
- LineTo(box.right-2,box.top+3);
- if (((**((*GetWindowGDevice(theDialog))->gdPMap)).pixelSize >= 8)) {
- greyColor.red = greyColor.green = greyColor.blue = 0x7777;
- RGBForeColor (&greyColor);
- MoveTo(box.left+1,box.top+1);
- LineTo(box.right-1,box.top+1);
- MoveTo(box.left+1,box.top+4);
- LineTo(box.right-1,box.top+4);
- }
- RGBForeColor(&oldColor);
- }
-
- pascal void OutlineOK (DialogPtr dp, short item)
- /*
- userItem drawing routine for outlining the default button in the dialog box
- */
- {
- Rect r;
- Handle h;
- short itemType;
-
- item = ok;
- GetDItem (dp, item, &itemType, &h, &r);
- PenNormal ();
- PenSize (3, 3);
- InsetRect (&r, -4, -4);
- FrameRoundRect (&r, 16, 16);
- PenNormal ();
- }
-
- pascal void DrawSunkFrame (DialogPtr dp, short item)
- /*
- User item drawing routine for drawing the 3-D-like frame for the preview image.
- */
- {
- Rect r;
- Handle h;
- short itemType;
- RGBColor darkGray, lightGray;
- RGBColor oldForeColor;
- Boolean bwMode = (((**((*GetWindowGDevice(dp))->gdPMap)).pixelSize < 8));
-
- GetDItem (dp, item, &itemType, &h, &r);
- darkGray.red = darkGray.green = darkGray.blue = kDarkGray;
- lightGray.red = lightGray.green = lightGray.blue = kLightGray;
- GetForeColor(&oldForeColor);
- if (!bwMode) {
- RGBForeColor(&darkGray);
- MoveTo(r.left,r.bottom-1);
- LineTo(r.left,r.top);
- LineTo(r.right-1,r.top);
- } else RGBForeColor((RGBColor*)RGBBlack);
- MoveTo(r.left+1,r.bottom-2);
- LineTo(r.left+1,r.top+1);
- LineTo(r.right-2,r.top+1);
- if (!bwMode) {
- RGBForeColor(&lightGray);
- MoveTo(r.right-1,r.top+1);
- LineTo(r.right-1,r.bottom-1);
- LineTo(r.left,r.bottom-1);
- } else RGBForeColor((RGBColor*)RGBBlack);
- MoveTo(r.right-2,r.top+2);
- LineTo(r.right-2,r.bottom-2);
- LineTo(r.left+1,r.bottom-2);
- InsetRect(&r,2,2);
- RGBForeColor((RGBColor*)RGBBlack);
- FrameRect(&r);
- RGBForeColor(&oldForeColor);
- }
-
- void RectLocalToGlobal (Rect *theRect)
- {
- LocalToGlobal((Point *)theRect);
- LocalToGlobal((Point *)(&(theRect->bottom)));
- }
-
- pascal void DrawFilteredImage (DialogPtr dp, short item)
- /*
- User item drawing routine to draw the preview image
- */
- {
- Rect r;
- Handle h;
- short itemType;
- GDHandle oldGD,destGD = GetWindowGDevice(dp);
- ParamsHandle theParams = (ParamsHandle)GetWRefCon(dp);
- FiltParamPtr params = (**theParams).filterParamBlock;
- unsigned char oldState;
- PixMapHandle filtered;
- RGBColor oldFore,oldBack;
-
- if (*((short*)SysVersion)<0x700) {
- filtered = params->destImage->portPixMap;
- } else {
- filtered = GetGWorldPixMap (params->destImage);
- }
- GetDItem (dp, item, &itemType, &h, &r);
- oldGD = GetGDevice();
- SetGDevice (destGD);
- GetForeColor (&oldFore);
- GetBackColor (&oldBack);
- RGBForeColor ((RGBColor*)RGBBlack);
- RGBBackColor ((RGBColor*)RGBWhite);
- oldState = HGetState ((Handle)((CGrafPtr)dp)->portPixMap);
- HLock ((Handle)((CGrafPtr)dp)->portPixMap);
- CopyBits((BitMap*)*filtered,&(dp->portBits),&((**filtered).bounds),&r,srcCopy,nil);
- HSetState ((Handle)((CGrafPtr)dp)->portPixMap,oldState);
- RGBForeColor (&oldFore);
- RGBBackColor (&oldBack);
- SetGDevice (oldGD);
- }
-
- pascal void UpdateImage (ControlHandle ctrl, short *value)
- /*
- Callback routine for the control to update the preview image. Gets called by
- VideoShop's slider control definition while the control is being dragged.
- */
- {
- DialogPtr dp = (**ctrl).contrlOwner;
- ParamsHandle theParams = (ParamsHandle)GetWRefCon(dp);
- /* Get the parameters handle from the window's refcon */
- FiltParamPtr params = (**theParams).filterParamBlock;
- /* Get the parameter block we stuffed there */
- PixMapHandle src = params->srcImage;
- GrafPtr oldPort;
-
- (**theParams).filterIntensity = *value;
- DoFilter (src, params->destImage, 100, 100, (**theParams).filterIntensity);
- GetPort (&oldPort);
- SetPort (dp);
- DrawFilteredImage (dp,imageItem);
- SetPort (oldPort);
- }
-
- void SetupDItems (DialogPtr dp)
- /*
- Set up the dialog items
- */
- {
- short itemType;
- Handle h;
- Rect r;
-
- /* Point default useritem to default button outline routine */
- GetDItem (dp, defaultItem, &itemType, &h , &r);
- SetDItem (dp, defaultItem, itemType, (Handle) &OutlineOK, &r);
-
- /* Point divider lines useritem to dividing lines drawing routine */
- GetDItem (dp, dividerLinesItem, &itemType, &h , &r);
- SetDItem (dp, dividerLinesItem, itemType, (Handle) DrawLines, &r);
-
- /* Point preview image item to image blitting routine */
- GetDItem (dp, imageItem, &itemType, &h , &r);
- SetDItem (dp, imageItem, itemType, (Handle) &DrawFilteredImage, &r);
-
- /* Point preview image frame item to drawing routine */
- GetDItem (dp, frameItem, &itemType, &h , &r);
- SetDItem (dp, frameItem, itemType, (Handle) &DrawSunkFrame, &r);
-
- /* Point control's refCon to the the dragging callback routine */
- GetDItem (dp, intensityItem, &itemType, &h, &r);
- SetCRefCon((ControlHandle)h,(long)UpdateImage);
- }
-
- void RecalcDItems (ParamsHandle p, DialogPtr dp)
- {
- short itemType;
- ControlHandle ctrl;
- Rect r;
-
- GetDItem (dp, intensityItem, &itemType, (Handle*)&ctrl, &r);
- (**p).filterIntensity = GetCtlValue(ctrl);
-
- GetDItem (dp, forwardItem, &itemType, (Handle*)&ctrl, &r);
- SetCtlValue(ctrl,1-(**p).backward);
- GetDItem (dp, backwardItem, &itemType, (Handle*)&ctrl, &r);
- SetCtlValue(ctrl,(**p).backward);
- }
-
- FiltErr DoParameters (FiltParamPtr params)
- /*
- Prompt the user for parameters if necessary.
- */
- {
- DialogPtr dp;
- DialogTHndl dt;
- ParamsHandle theParams;
- short item;
- GrafPtr oldPort;
- GWorldFlags pmStateSrc,pmStateDest;
- unsigned char stateSrc,stateDest;
- PixMapHandle src,dest;
-
- /* If we didn't get passed a params handle, allocate and initialize it */
- if (!params->parameters) {
- theParams = (ParamsHandle)NewHandleClear(sizeof(Params));
- if (!theParams) return (FiltErrOutOfMemory|MemError());
- (**theParams).filterIntensity = 80;
- } else
- /*
- Otherwise, we just return. If we required specific hardware or mounds of
- memory we would check here.
- */
- return (noErr);
-
- src = params->srcImage;
-
- /* Prepare for previewing filter */
-
- /* Get the image pixmaps, dealing with pre-System 7 GetGWorldPixMap bug */
- if (*((short*)SysVersion)<0x700) {
- dest = params->destImage->portPixMap;
- } else {
- dest = GetGWorldPixMap (params->destImage);
- }
-
- /* Save pixmaps' state and lock the buffers */
- pmStateSrc = GetPixelsState(src);
- LockPixels (src);
- stateSrc = HGetState ((Handle)src);
- MoveHHi ((Handle)src);
- HLock ((Handle)src);
- pmStateDest = GetPixelsState(dest);
- LockPixels (dest);
- stateDest = HGetState ((Handle)dest);
- MoveHHi ((Handle)dest);
- HLock ((Handle)dest);
-
- (**theParams).filterParamBlock = params;
-
- /* Load in the dialog and reposition it in the best device */
- dt = (DialogTHndl) GetResource ('DLOG', dialogID);
- HNoPurge ((Handle) dt);
- CenterDialogBestDevice (dt);
-
- /* Show it */
- dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
- GetPort (&oldPort);
- SetPort (dp);
-
- /* Save our params handle in the window refcon for the user items */
- SetWRefCon(dp,(long)theParams);
-
- /* Setup the user items and initialize all controls to initial state */
- SetupDItems(dp);
- RecalcDItems(theParams,dp);
-
- DoFilter (src, params->destImage, 100, 100, (**theParams).filterIntensity);
-
- do {
- ModalDialog (nil, &item);
- switch (item) {
- case forwardItem:
- (**theParams).backward=false;
- RecalcDItems(theParams,dp);
- break;
- case backwardItem:
- (**theParams).backward=true;
- RecalcDItems(theParams,dp);
- break;
- default:
- break;
- }
- } while (item != ok && item != cancel);
-
- SetPort (oldPort);
- DisposDialog (dp);
- HPurge ((Handle) dt);
-
- /* Restore pixel maps state */
- HSetState ((Handle)src,stateSrc);
- SetPixelsState(src,pmStateSrc);
- HSetState ((Handle)dest,stateDest);
- SetPixelsState(dest,pmStateDest);
-
- if (item == cancel) {
- DisposHandle((Handle)theParams);
- params->parameters = nil;
- return (FiltErrReported);
- }
- params->parameters=(Handle)theParams;
- return (noErr);
- }
-
- void DoFilter (PixMapHandle src, GWorldPtr destGW, short current,
- short total, short intensity)
- /* Perform the filtering operation */
- {
- #pragma unused(current,total,intensity,newRect)
- Rect r = (**src).bounds,newRect;
- RGBColor oldFore,oldBack;
- GWorldPtr oldGW;
- PixMapHandle dest;
- GDHandle oldGD;
-
- /* Check for pre-System 7 QD bug (GetGWorldPixMap didn't work) */
-
- if (*((short*)SysVersion)<0x700) {
- dest = destGW->portPixMap;
- } else {
- dest = GetGWorldPixMap (destGW);
- }
-
- /* Save state */
-
- GetGWorld (&oldGW,&oldGD);
- SetGWorld (destGW,GetGWorldDevice(destGW));
- GetForeColor (&oldFore);
- GetBackColor (&oldBack);
- RGBForeColor ((RGBColor*)RGBBlack);
- RGBBackColor ((RGBColor*)RGBWhite);
-
- /* perform filter */
-
- CopyBits((BitMap*)*src,(BitMap*)*dest,&r,&r,srcCopy,nil);
-
- /* Wait for accelerators */
- while (!(QDDone((GrafPtr)destGW)));
-
- /* Restore state */
-
- RGBForeColor (&oldFore);
- RGBBackColor (&oldBack);
- SetGWorld(oldGW,oldGD);
- }
-
- FiltErr DoProcessFrame (FiltParamPtr params, short currentStep, short totalSteps)
- {
- GWorldFlags pmStateSrc,pmStateDest;
- GWorldPtr destGW;
- PixMapHandle src,dest;
- unsigned char stateSrc,stateDest;
- ParamsHandle p = (ParamsHandle)params->parameters;
-
- if (TestAbort (params)) return (FiltErrReported);
-
- src = params->srcImage;
- destGW = params->destImage;
-
- /* Check for pre-System 7 QD bug (GetGWorldPixMap didn't work) */
- if (*((short*)SysVersion)<0x700) {
- dest = destGW->portPixMap;
- } else {
- dest = GetGWorldPixMap (destGW);
- }
-
- /* Spin the wheel */
- UpdateProgress (params,0,2);
-
- /* save offscreen pixels state and lock them down for drawing */
- pmStateSrc = GetPixelsState(src);
- LockPixels (src);
- stateSrc = HGetState ((Handle)src);
- MoveHHi ((Handle)src);
- HLock ((Handle)src);
-
- pmStateDest = GetPixelsState(dest);
- LockPixels (dest);
- stateDest = HGetState ((Handle)dest);
- MoveHHi ((Handle)dest);
- HLock ((Handle)dest);
-
- /* perform filter */
- if ((**p).backward) {
- DoFilter (src,destGW,totalSteps-currentStep,totalSteps,(**p).filterIntensity);
- } else {
- DoFilter (src,destGW,currentStep,totalSteps,(**p).filterIntensity);
- }
-
- UpdateProgress (params,2,2);
-
- HSetState ((Handle)src,stateSrc);
- SetPixelsState(src,pmStateSrc);
- HSetState ((Handle)dest,stateDest);
- SetPixelsState(dest,pmStateDest);
-
- return (noErr);
- }
-