unit UMacroDef; {Contributed by Edward J. Huff } {Copyright is hereby waived: UMacroDef.p is in the public domain.} {Instructions for the use of these modules:} {User coded extensions to the Image Macro Language are supported by the} {modules UMacroDef.p and UMacroRun.p. Generally, each extension package} {should be placed in it's own Pascal file named UMYourPack.p and placed in} {the project after UMacroDef.p and before UMacroRun.p. } {These packages should be modeled after UMSample.p. } {Instructions for doing this are found in UMSample.p.} {It should normally be possible to implement the desired extensions without } {changing any modules other than UMacroDef.p and UMacroRun.p.} {Places where changes are required start with --(n)-- and end with ==(n)==.} {One change is required in UMacroDef.p, and seven are required in UMacroRun.p.} {How to add a user coded macro language extension: } {(1) Decide on the extension type: command, function, or string function,} { denoted by UserCommandT, UserFuncT, or UserStrFuncT.} { This will be included in the AddUMSym call which adds your extension} { to the symbol table. These instructions are written assuming that} { your package defines only one extension, but it may define more than} { one. The sample package defines SampleCommand, SampleFunc,} { and SampleStrFunc. } {(2) Pick a name for your extension package, for example, "YourPack".} { (The name should not be too long, 8 characters is ok. The first problem} { you notice if the name is too long is that the Pascal Windows menu shows} { É on the end of the file name. There might be more serious problems.) } { Open UMSample.p and follow the directions there to create a new module} { UMYourPack.p. Come back here after creating the module and} { changing all "sample" to "YourPack". Note that this will define} { five interface procedures: UMYourPackInit, UMYourPackFinal, } { UMYourPackAdd, UMYourPackLookup, and UMYourPackRun. } { You will add calls to these five procedures to UMacroRun.p later.} {(3) Pick a name for the extension. Make sure it isn't already used.} { Only the first SymbolSize (=12) characters are significant.} { You can put more than one extension in your package. The} { name goes into the AddUMSym call and into the UserCommandType} { declaration below.} {(4) Decide on the arguments. If you need more than UserMacroMaxArgs,} { be sure to increase the value of the constant below. } { Each argument must be an integer (rounded and stored as longint),} { a real, or a string (at most one string). These may be var arguments.} { String functions cannot also have a var string argument.} { String functions with one string argument are legal but be sure to copy} { the string argument if its value is needed after setting the output string,} { since both are stored in the same place.} { Integers are stored as long integers, NOT as extended. } { Support is provided to make it easy to operate on more than one image} { in a single command, and to operate on ROI's. If the argument is} { declared a "pic", then the value is interpreted as either a picNumber} { or a pidNumber. If the specified image does not exist, a macro error } { is given highlighting the bad value. If there is no ROI, then the} { whole image is taken to be the ROI. If the ROI is not rectangular, a} { macro error is given.} {(5) Add a User Command item to UserCommandType. Put UC on the end of the name.} { This is done at --Add User Command items here-- in UMacroDef.p.} {(6) Follow the instructions in UMacroRun.p: make changes at seven places.} { 1. "uses" clause, 2. InitUserMacros, 3. FinalUserMacros, 4. AddUserMacros } { 5. LookupUserMacro, 6. and 7. DoUserMacro. These seven changes consists} { of adding calls to the five procedures which you defined in UMYourPack.p,} { the uses clause, and an "else if" statement in the RequiresUser macro command.} {(7) Follow the instructions in UMYourPack.p to create the extensions.} {Thats all it takes to add an extension to the Image macro language.} interface uses QuickDraw, Palettes, PrintTraps, Globals, Utilities; const UserMacroMaxArgs = 7; {Increase if necessary} type UserCommandType = ( {-----------------Add User Command items here--------------} {changes here must be reflected at items (5) and (7) in UMacroRun.p} {(5) is LookupUserMacro, (7) is DoUserMacro.} {Timer} StartElapsedUC, MeasureElapsedUC, StartDelayUC, KillDelayUC, WaitDelayUC,{} StartPeriodicUC, KillPeriodicUC, AdjustPeriodicUC, WaitPeriodicUC, {Utilities} dumpSymbolTableUC, getFolderUC, getDefFolderUC, setDefFolderUC,{} getMemoUC, setMemoUC, importOntoUC, getPicNameUC, {} numToHexUC, hexToNumUC, {Sample} sampleCommandUC, sampleFuncUC, sampleStrFuncUC, {Pixel16u} minMax16uUC, minMax32sUC, LinLUT16uTo8UC,{} Cnvrt16uTo8UC, Cnvrt8To16uUC, Convolve16uUC, {} Median16uUC, radMedian16uUC, MinSpatial16uUC,{} GGDilate16uUC, GGErode16uUC,{} Add16uTo32sUC, Cnvrt32sT16uUC,{} Add16uUC, Sub16uUC, Mpy16uUC, Div16uUC, Ratio16uUC, Lrg16uUC, Sml16uUC, {} AddK16uUC, SubK16uUC, MpyK16uUC, DivK16uUC, MpyDivK16uUC, LrgK16uUC, SmlK16uUC,{} SqzMask16uUC, ExpMask16uUC, CnvMsk16uTo8UC, SqzMask8uUC, ExpMask8uUC, {} NewView16uUC, NMaskView16uUC, FindView16uUC, GaussRand16uUC, NormSInvUC,{} Fill16uUC, ApplyLUT16uUC,{} {Pixel32r} Cnvrt8To32rUC, Cnvrt32rTo8UC, Cnvrt16uT32rUC, Cnvrt32rT16uUC,{} Add32rUC, Sub32rUC, Mpy32rUC, Div32rUC, Lrg32rUC, Sml32rUC, {} AddK32rUC, SubK32rUC, MpyK32rUC, DivK32rUC, LrgK32rUC, SmlK32rUC,{} minMax32rUC, Min32rUC, Max32rUC, Sqrt32rUC, Ln32rUC, Exp32rUC,{} LeastSqr32rUC, ExpFtStep32rUC, Fill32rUC,{} {GetPutPixel} getPixel8UC, getPixVec8UC, putPixel8UC, putPixVec8UC,{} getPixel16uUC, getPixVec16uUC, putPixel16uUC, putPixVec16uUC,{} getPixel16sUC, getPixVec16sUC, putPixel16sUC, putPixVec16sUC,{} getPixel32sUC, getPixVec32sUC, putPixel32sUC, putPixVec32sUC,{} getPixel32rUC, getPixVec32rUC, putPixel32rUC, putPixVec32rUC,{} getPixel96rUC, getPixVec96rUC, putPixel96rUC, putPixVec96rUC,{} {Quantile} XYQuantileUC, ZQuantileUC,{} {Crest} CrestPathwayUC,{} {Markup} Dilate8CircularUC, Sum16uMarkUC, Sum16sMarkUC,{} MarkupPicNumberUC, MarkupData16UC, MarkupData8UC, MarkupMarksUC, {} MarkupBkgUC, MarkupShowUC, MarkupHideUC, MarkupPasteKernelUC, {} MarkupValleysUC, MarkupRidgesUC, MarkupBkgCoefUC, MarkupBkgMinUC, {} MarkupBkgDeltaUC, MarkupBkgConeUC, MarkupBkgExponentialUC, MarkupDilateUC, {} MarkupErodeUC, MarkupCalcBkgUC, MarkupCalcHistUC, MarkupScale16bUC, {} MarkupScaleMinUC, MarkupScaleMaxUC, MarkupMake16bUC,{} MarkupavgToBkgUC, MarkupBkgSubUC, MarkedSumUC, MarkedBkgUC,{} {scion1200} s12FindNuBusRamUC, s12GetNBRamBaseUC, s12GetNBRamSizeUC,{} s12SetNBRamBaseUC, s12SetNBRamSizeUC, s12FakeNBRamUC, {} s12SetHeightUC, s12SetWidthUC, s12SetBrightUC, s12SetContrastUC, {} s12GetHeightUC, s12GetWidthUC, s12GetBrightUC, s12GetContrastUC, {} s12Start30FPSUC, s12Done30FPSUC, s12IntegrateFramesUC, {} s12SmoothRealUC, s12NumToHexUC,{} s12AddRealUC, s12AddRealConsUC, s12Cnv16ToRealUC, s12Cnv8ToRealUC, s12CnvRTo16UC, {} s12CnvRealTo8UC, s12DivRealUC, s12DivRealConsUC, s12LrgRealUC, s12LrgRealConsUC, {} s12MaxRealUC, s12MinRealUC, s12MpyRealUC, s12MpyRealConsUC, {} s12SmlRealUC, s12SmlRealConsUC, s12SubRealUC, s12SubRealConsUC,{} {TextBuf} FromTxBUC, FromTxWUC, AfterTxBUC, PasteAfterTxBUC, ReadAfterTxBUC, {} CopyFromTxBUC, WriteTxBUC, LengthTxBUC, LengthTxWUC, {} TxBNumberUC, TxBidNumberUC, TxWNumberUC, TxWidNumberUC, {} nTxBsUC, nTxWsUC, SelectTxBUC, SelectTxWUC,{} DeleteTxBUC, CopyTxBToTxBUC, CopyTxWToTxBUC, MakeTxWSelecUC, GetTxWSelectUC,{} SearchTxWUC, SearchTxBUC, MacrosFromTxBUC, DisposeTxBUC, {} TxBExistsUC, TxWExistsUC, MakeNewTxBUC, {=================End User Command items=================} requiresUserUC); UserMacroArgt = ( {} UMATinteger, UMATreal, UMATstring, {} UMATintvar, UMATrealvar, UMATstringvar,{} UMATpic); UserMacroRoi = record Skip: LongInt; {equals BytesPerRow - roi.Width} Base: ptr; {address of top left byte of the roi.} Width: LongInt; {width of roi in bytes} Height: LongInt; {height of roi in lines} end; UserMacroArg = record atype: UserMacroArgt;{set in lookup routine, do not change later.} varIX: Integer;{do not change} aval: Extended;{used for real argument values} ival: LongInt; {used for integer argument values} infop: InfoPtr; roi: UserMacroRoi; {info needed to rapidly access pixels of roi} wasRoi: Boolean; {true if rectangular Roi should be restored} end; UserMacroArgs = record UserMacroCommand: UserCommandType; UserToken: TokenType; {one of UserCommandT, UserFuncT, UserStrFuncT} nArgs: integer; {set in lookup routine, do not change later} arg: array[1..UserMacroMaxArgs] of UserMacroArg; FuncResult: Extended; ErrorOccurred: Boolean; str: Str255; {string argument, string var return, string function return} end; const {Values for field UKind in UserWindowRec (defined in Globals.p)} {UKind is initialized to zero} MarkupUKind = 1; View16uUKind = 2; var UMInitOK: Boolean; procedure AddUMSym (str: Str255; tok: TokenType; cmd: UserCommandType); {Some of these procedures might better be put in Utilities.p...} procedure checkPixelWidth (w: integer; var uma: UserMacroArgs; i: integer); procedure checkOutputConflict (var uma: UserMacroArgs; n: integer); function isAPic (thePic: InfoPtr): Boolean; implementation procedure AddUMSym (str: Str255; tok: TokenType; cmd: UserCommandType); var i, j: integer; name: SymbolType; begin if tok <> UserCommandT then if tok <> UserFuncT then if tok <> UserStrFuncT then begin PutMessage('Bad TokenType argument to AddUMSym in UMacroDef.p'); UMInitOK := false; exit(AddUMSym); end; {to make AddUMSym calls somewhat foolproof, automatically convert } {to lower case, and blank fill or truncate to SymbolSize (=12) characters.} MakeLowerCase(str); name := blanksymbol; j := length(str); if j > SymbolSize then j := SymbolSize; for i := 1 to j do name[i] := str[i]; with MacrosP^ do for i := 1 to nSymbols do if SymbolTable[i].symbol = name then begin PutMessage(concat('Duplicate symbol ''', name, ''' = ''', str, ''' in UMacroDef.p')); UMInitOK := false; exit(AddUMSym); end; if nSymbols >= MaxSymbols then begin PutMessage('Symbol table overflow in UMacroDef.p'); UMInitOK := false; exit(AddUMSym); end; nSymbols := nSymbols + 1; with MacrosP^.SymbolTable[nSymbols] do begin symbol := name; tType := tok; cType := CommandType(cmd); loc := 0; end; end; procedure checkOutputConflict (var uma: UserMacroArgs; n: integer); var i: integer; p: InfoPtr; begin with uma do begin if errorOccurred then exit(checkOutputConflict); p := arg[n].infop; for i := 1 to nArgs do if i <> n then with arg[i] do if (atype = UMATpic) and (infop = p) then begin errorOccurred := true; str := 'Output image must be distinct from each input image'; end; end; end; procedure checkPixelWidth (w: integer; var uma: UserMacroArgs; i: integer); begin with uma, arg[i], infop^ do begin if errorOccurred then exit(checkPixelWidth); if atype <> UMATpic then begin errorOccurred := true; str := 'checkPixelWidth in UMacroDef.p'; exit(checkPixelWidth); end; if PixelsPerLine mod w <> 0 then errorOccurred := true else if BytesPerRow mod w <> 0 then errorOccurred := true else if WasRoi then if RoiRect.left mod w <> 0 then errorOccurred := true else if RoiRect.right mod w <> 0 then errorOccurred := true; if errorOccurred then str := 'Multibyte pixel image or selection covers partial pixel'; end; end; function isAPic (thePic: InfoPtr): Boolean; var n: integer; begin isAPic := true; if thePic <> nil then if thePic <> NoInfo then for n := 1 to nPics do if thePic = InfoPtr(WindowPeek(PicWindow[n])^.RefCon) then exit(isAPic); isAPic := false; end; end.