home *** CD-ROM | disk | FTP | other *** search
- {
-
- SampleFilt.p
-
- Sample Filter Effect for DiVA VideoShop
-
- 04/28/92 Ivçn Cavero Bela£nde
-
-
- }
-
- UNIT SampleFilter;
-
- INTERFACE
-
- USES
- Types,Memory,Resources,QuickDraw,QDOffscreen,Dialogs,OSUtils,Packages,Errors,
- ToolUtils,SysEqu,GestaltEqu,DiVAFilter;
-
- FUNCTION FilterEntryPoint(selector: INTEGER; params: FiltParamPtr; VAR data: LONGINT;
- currentStep, totalSteps: INTEGER): FiltErr;
-
- FUNCTION DoParameters(params: FiltParamPtr): FiltErr;
-
- FUNCTION DoProcessFrame(params: FiltParamPtr; currentStep, totalSteps: INTEGER):
- FiltErr;
-
- PROCEDURE DoFilter(src: PixMapHandle; destGW: GWorldPtr; current,total,intensity:
- INTEGER);
-
- IMPLEMENTATION
-
- CONST
-
- { Shades of gray for 3D objects }
- kLightGray = $ffff;
- kMediumGray = $dddd;
- kDarkGray = $aaaa;
-
- { Dialog item constants }
-
- dialogID = 16001;
- defaultItem = 3;
- intensityItem = 5;
- dividerLinesItem = 7;
- imageItem = 9;
- frameItem = 10;
- forwardItem = 11;
- backwardItem = 12;
-
- TYPE
-
- ParamsRecord = RECORD
- filterIntensity: INTEGER;
- backward: BOOLEAN;
- filterParamBlock: FiltParamPtr; { Paramblk for use of custom ditems }
- END;
-
- ParamsPtr = ^ParamsRecord;
- ParamsHandle = ^ParamsPtr;
-
- RGBColorPtr = ^RGBColor;
-
- FUNCTION FilterEntryPoint(selector: INTEGER; params: FiltParamPtr; VAR data: LONGINT;
- currentStep, totalSteps: INTEGER): FiltErr;
- BEGIN
- CASE selector OF
- FiltParameters:
- FilterEntryPoint := DoParameters (params);
- FiltPrepare:
- FilterEntryPoint := noErr;
- FiltStart:
- FilterEntryPoint := noErr;
- FiltProcessFrame:
- FilterEntryPoint := DoProcessFrame(params,currentStep,totalSteps);
- FiltFinish:
- FilterEntryPoint := noErr;
- OTHERWISE
- FilterEntryPoint := -1;
- END;
- END;
-
- FUNCTION DoTestAbort(codeAddress: ProcPtr): BOOLEAN;
- { Inline code to call the TestAbort function }
- INLINE $205F, { move.l (a7)+,a0 pop procPtr from stack }
- $4E90; { jsr (a0) and call it }
-
- FUNCTION TestAbort (params: FiltParamPtr): BOOLEAN;
- BEGIN
- TestAbort := DoTestAbort(params^.abortProc);
- END;
-
- PROCEDURE DoUpdateProgress(done, total: LONGINT; codeAddress: ProcPtr);
- { Inline code to call the UpdateProgress function }
- INLINE $205F, { move.l (a7)+,a0 pop procPtr from stack }
- $4E90; { jsr (a0) and call it }
-
- PROCEDURE UpdateProgress(params: FiltParamPtr; done, total: LONGINT);
- BEGIN
- DoUpdateProgress(done,total,params^.progressProc);
- END;
-
- PROCEDURE CenterDialogBestDevice(dt: DialogTHndl);
- {
- 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.
- }
- VAR
- width, height: INTEGER;
- maxDevice: GDHandle;
- grayRgn: RgnHandle;
- r,dr: Rect;
- BEGIN
- grayRgn := GetGrayRgn;
- r := grayRgn^^.rgnBBox;
-
- 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)) DIV 2,
- (height - (dr.bottom-dr.top) - GetMBarHeight) DIV 3 + GetMBarHeight);
- dt^^.boundsRect := dr;
- END;
-
- FUNCTION GetWindowGDevice(w: WindowPtr): GDHandle;
- {
- 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).
- }
- VAR
- r: Rect;
- oldPort: GrafPtr;
- BEGIN
- GetPort(oldPort);
- SetPort(w);
- r := w^.portRect;
- LocalToGlobal(r.topLeft);
- LocalToGlobal(r.botRight);
- GetWindowGDevice := GetMaxDevice(r);
- SetPort (oldPort);
- END;
-
- PROCEDURE DrawLines(theDialog: DialogPtr; itemNo: INTEGER);
- {
- userItem drawing routine for dividing lines (with shadow)
- }
- VAR
- oldColor, greyColor: RGBColor;
- itemType: INTEGER;
- me: Handle;
- box: Rect;
- BEGIN
- GetDItem(theDialog,itemNo,itemType,me,box);
- GetForeColor(oldColor);
- RGBForeColor(RGBColorPtr(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) THEN
- BEGIN
- greyColor.red := $7777;
- greyColor.green := $7777;
- greyColor.blue := $7777;
- 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);
- END;
- RGBForeColor(oldColor);
- END;
-
-
- PROCEDURE OutlineOK(dp: DialogPtr; item: INTEGER);
- {
- userItem drawing routine for outlining the default button in the dialog box
- }
- VAR
- r: Rect;
- h: Handle;
- itemType: INTEGER;
- BEGIN
- item := ok;
- GetDItem (dp, item, itemType, h, r);
- PenNormal;
- PenSize (3, 3);
- InsetRect (r, -4, -4);
- FrameRoundRect (r, 16, 16);
- PenNormal;
- END;
-
-
- PROCEDURE DrawSunkFrame(dp: DialogPtr; item: INTEGER);
- {
- User item drawing routine for drawing the 3-D-like frame for the preview image.
- }
- VAR
- r: Rect;
- h: Handle;
- itemType: INTEGER;
- oldForeColor, darkGray, lightGray: RGBColor;
- bwMode: Boolean;
- BEGIN
- bwMode := (GetWindowGDevice(dp)^^.gdPMap^^.pixelSize < 8);
- GetDItem (dp, item, itemType, h, r);
- darkGray.red := kDarkGray;
- darkGray.green := kDarkGray;
- darkGray.blue := kDarkGray;
- lightGray.red := kLightGray;
- lightGray.green := kLightGray;
- lightGray.blue := kLightGray;
- GetForeColor(oldForeColor);
- if (NOT bwMode) THEN
- BEGIN
- RGBForeColor(darkGray);
- MoveTo(r.left,r.bottom-1);
- LineTo(r.left,r.top);
- LineTo(r.right-1,r.top);
- END
- ELSE RGBForeColor(RGBColorPtr(RGBBlack)^);
- MoveTo(r.left+1,r.bottom-2);
- LineTo(r.left+1,r.top+1);
- LineTo(r.right-2,r.top+1);
- IF (NOT bwMode) THEN
- BEGIN
- RGBForeColor(lightGray);
- MoveTo(r.right-1,r.top+1);
- LineTo(r.right-1,r.bottom-1);
- LineTo(r.left,r.bottom-1);
- END
- ELSE RGBForeColor(RGBColorPtr(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(RGBColorPtr(RGBBlack)^);
- FrameRect(r);
- RGBForeColor(oldForeColor);
- END;
-
- PROCEDURE RectLocalToGlobal (VAR r:Rect);
- BEGIN
- LocalToGlobal(r.topLeft);
- LocalToGlobal(r.botRight);
- END;
-
- PROCEDURE DrawFilteredImage (dp: DialogPtr; item: INTEGER);
- {
- User item drawing routine to draw the preview image
- }
- VAR
- r: Rect;
- h: Handle;
- itemType: INTEGER;
- oldGD, destGD: GDHandle;
- theParams: ParamsHandle;
- params: FiltParamPtr;
- oldState: SignedByte;
- filtered: PixMapHandle;
- oldFore,oldBack: RGBColor;
-
- BEGIN
- destGD := GetWindowGDevice(dp);
- theParams := ParamsHandle(GetWRefCon(dp));
- params := theParams^^.filterParamBlock;
-
- IF (IntegerPtr(SysVersion)^<$700) THEN
- filtered := params^.destImage^.portPixMap
- ELSE
- filtered := GetGWorldPixMap (params^.destImage);
-
- GetDItem (dp, item, itemType, h, r);
- oldGD := GetGDevice;
- SetGDevice (destGD);
- GetForeColor (oldFore);
- GetBackColor (oldBack);
- RGBForeColor (RGBColorPtr(RGBBlack)^);
- RGBBackColor (RGBColorPtr(RGBWhite)^);
- oldState := HGetState (Handle(CGrafPtr(dp)^.portPixMap));
- HLock (Handle(CGrafPtr(dp)^.portPixMap));
- CopyBits(BitMapHandle(filtered)^^,dp^.portBits,filtered^^.bounds,r,srcCopy,nil);
- HSetState (Handle(CGrafPtr(dp)^.portPixMap),oldState);
- RGBForeColor (oldFore);
- RGBBackColor (oldBack);
- SetGDevice (oldGD);
- END;
-
- PROCEDURE UpdateImage (ctrl: ControlHandle; VAR value: INTEGER);
- {
- Callback routine for the control to update the preview image. Gets called by
- VideoShop's slider control definition while the control is being dragged.
- }
- VAR
- dp: DialogPtr;
- theParams: ParamsHandle;
- params: FiltParamPtr;
- src: PixMapHandle;
- oldPort: GrafPtr;
- BEGIN
- dp := ctrl^^.contrlOwner;
- theParams := ParamsHandle(GetWRefCon(dp));
- { Get the parameters handle from the window's refcon }
- params := theParams^^.filterParamBlock;
- { Get the parameter block we stuffed there }
- src := params^.srcImage;
- theParams^^.filterIntensity := value;
- DoFilter (src, params^.destImage, 100, 100, theParams^^.filterIntensity);
- GetPort (oldPort);
- SetPort (dp);
- DrawFilteredImage (dp,imageItem);
- SetPort (oldPort);
- END;
-
- PROCEDURE SetupDItems (dp: DialogPtr);
- VAR
- itemType: INTEGER;
- h: Handle;
- r: Rect;
- BEGIN
- { 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),LONGINT(@UpdateImage));
- END;
-
- PROCEDURE RecalcDItems (p: ParamsHandle; dp: DialogPtr);
- VAR
- itemType: INTEGER;
- fwd, back: ControlHandle;
- r: Rect;
- BEGIN
- GetDItem (dp, intensityItem, itemType, Handle(fwd), r);
- p^^.filterIntensity := GetCtlValue(fwd);
-
- GetDItem (dp, forwardItem, itemType, Handle(fwd), r);
- GetDItem (dp, backwardItem, itemType, Handle(back), r);
- IF (p^^.backward) THEN BEGIN
- SetCtlValue(fwd,0);
- SetCtlValue(back,1);
- END
- ELSE BEGIN
- SetCtlValue(fwd,1);
- SetCtlValue(back,0);
- END;
- END;
-
- FUNCTION DoParameters (params: FiltParamPtr): FiltErr;
- {
- Prompt the user for parameters if necessary.
- }
- VAR
- dp: DialogPtr;
- dt: DialogTHndl;
- theParams: ParamsHandle;
- item: INTEGER;
- oldPort: GrafPtr;
- pmStateSrc,pmStateDest: GWorldFlags;
- stateSrc,stateDest: SignedByte;
- src,dest: PixMapHandle;
- dummy: BOOLEAN;
-
- BEGIN
- { If we didn't get passed a params handle, allocate and initialize it }
- IF (params^.parameters = NIL) THEN BEGIN
- theParams := ParamsHandle(NewHandleClear(sizeof(ParamsRecord)));
- IF (theParams = NIL) THEN BEGIN
- DoParameters := FiltErrOutOfMemory + MemError;
- Exit(DoParameters);
- END;
- theParams^^.filterIntensity := 80;
- END
- ELSE BEGIN
- {
- Otherwise, we just return. If we required specific hardware or mounds of
- memory we would check here.
- }
- DoParameters := noErr;
- Exit(DoParameters);
- END;
-
- src := params^.srcImage;
-
- { Prepare for previewing filter }
-
- { Get the image pixmaps, dealing with pre-System 7 GetGWorldPixMap bug }
- IF (IntegerPtr(SysVersion)^ < $700) THEN
- dest := params^.destImage^.portPixMap
- ELSE
- dest := GetGWorldPixMap (params^.destImage);
-
- { Save pixmaps' state and lock the buffers }
- pmStateSrc := GetPixelsState(src);
- dummy := LockPixels (src);
- stateSrc := HGetState (Handle(src));
- MoveHHi (Handle(src));
- HLock (Handle(src));
- pmStateDest := GetPixelsState(dest);
- dummy := 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,LONGINT(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);
-
- REPEAT
- ModalDialog (nil, item);
- CASE item OF
- forwardItem:
- BEGIN
- theParams^^.backward := false;
- RecalcDItems(theParams,dp);
- END;
- backwardItem:
- BEGIN
- theParams^^.backward := true;
- RecalcDItems(theParams,dp);
- END;
- END;
- UNTIL ((item = ok) OR (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) THEN BEGIN
- DisposHandle(Handle(theParams));
- params^.parameters := nil;
- DoParameters := FiltErrReported;
- Exit (DoParameters);
- END;
- params^.parameters := Handle(theParams);
- DoParameters := noErr;
- END;
-
- PROCEDURE DoFilter (src: PixMapHandle; destGW: GWorldPtr; current,total,
- intensity: INTEGER);
- { Perform the filtering operation }
- VAR
- r,newRect: Rect;
- oldFore,oldBack: RGBColor;
- oldGW: GWorldPtr;
- dest: PixMapHandle;
- oldGD: GDHandle;
- BEGIN
- r := src^^.bounds;
-
- { Check for pre-System 7 QD bug (GetGWorldPixMap didn't work) }
- IF (IntegerPtr(SysVersion)^ < $700) THEN
- dest := destGW^.portPixMap
- ELSE
- dest := GetGWorldPixMap (destGW);
-
- { Save state }
-
- GetGWorld (oldGW,oldGD);
- SetGWorld (destGW,GetGWorldDevice(destGW));
- GetForeColor (oldFore);
- GetBackColor (oldBack);
- RGBForeColor (RGBColorPtr(RGBBlack)^);
- RGBBackColor (RGBColorPtr(RGBWhite)^);
-
- { perform filter }
-
- CopyBits(BitMapHandle(src)^^,BitMapHandle(dest)^^,r,r,srcCopy,nil);
-
- { Wait for accelerators }
- WHILE (NOT (QDDone(GrafPtr(destGW)))) DO;
-
- { Restore state }
-
- RGBForeColor (oldFore);
- RGBBackColor (oldBack);
- SetGWorld(oldGW,oldGD);
- END;
-
- FUNCTION DoProcessFrame (params: FiltParamPtr; currentStep, totalSteps:
- INTEGER) : FiltErr;
-
- VAR
- pmStateSrc,pmStateDest: GWorldFlags;
- destGW: GWorldPtr;
- src,dest: PixMapHandle;
- stateSrc,stateDest: SignedByte;
- p: ParamsHandle;
- dummy: BOOLEAN;
- BEGIN
- p := ParamsHandle(params^.parameters);
-
- IF (TestAbort (params)) THEN BEGIN
- DoProcessFrame := FiltErrReported;
- Exit (DoProcessFrame);
- END;
-
- src := params^.srcImage;
- destGW := params^.destImage;
-
- { Check for pre-System 7 QD bug (GetGWorldPixMap didn't work) }
- IF (IntegerPtr(SysVersion)^ < $700) THEN
- dest := destGW^.portPixMap
- ELSE
- dest := GetGWorldPixMap (destGW);
-
- { Spin the beachball }
- UpdateProgress(params,0,2);
-
- { save offscreen pixels state and lock them down for drawing }
- pmStateSrc := GetPixelsState(src);
- dummy := LockPixels (src);
- stateSrc := HGetState (Handle(src));
- MoveHHi (Handle(src));
- HLock (Handle(src));
-
- pmStateDest := GetPixelsState(dest);
- dummy := LockPixels (dest);
- stateDest := HGetState (Handle(dest));
- MoveHHi (Handle(dest));
- HLock (Handle(dest));
-
- { perform filter }
- IF (p^^.backward) THEN
- 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);
-
- DoProcessFrame := noErr;
- END;
-
- END.
-