-- BitTunerCmds.mesa <<-- Written by Michael Plass on September 8, 1982 9:15 am>> <<-- Last edit by Michael Plass on November 3, 1982 12:10 pm>> DIRECTORY AIS, Graphics, GraphicsOps, CGScreen, Inline, JaMBasic, JaMInternal, JaMOps, Rope, Real, TJaMGraphics, TJaMGraphicsContexts, Runtime; BitTunerCmds: PROGRAM IMPORTS AIS, Graphics, GraphicsOps, CGScreen, Inline, JaMOps, Rope, Real, TJaMGraphics, TJaMGraphicsContexts, Runtime = BEGIN ROPE: TYPE = Rope.ROPE; Frame: TYPE = JaMInternal.Frame; PopRope: PROCEDURE [f: Frame] RETURNS [rope: ROPE] = { s: string JaMBasic.Object _ JaMOps.PopString[f.opstk]; C: PROC[c: CHAR] RETURNS [BOOLEAN] = {t[t.length]_c; t.length _ t.length+1; RETURN[FALSE]}; t: REF TEXT _ NEW[TEXT[s.length]]; t.length _ 0; JaMOps.StringForAll[s, C]; rope _ Rope.FromRefText[t]; }; PushRope: PROCEDURE [f: Frame, rope: ROPE] = { JaMOps.Push[ f.opstk, JaMOps.MakeString[LOOPHOLE[rope.ToRefText[], LONG STRING]] ]; }; AllocateBitmap: PROCEDURE [f: Frame] = { <<-- allocates storage of the requested size.>> side: NAT; side _ JaMOps.PopInteger[f.opstk]; bitImage _ GraphicsOps.NewBitmap[side, side]; bitImageDescriptor _ DescriptorFor[bitImage]; }; DrawBitmap: PROCEDURE [f: Frame] = { Paint: PROCEDURE [context: Graphics.Context] = { GraphicsOps.DrawBitmap[self: context, bitmap: bitImage, w: bitImage.width, h: bitImage.height, x: 0, y: 0, xorigin: 0, yorigin: bitImage.height]; }; TJaMGraphics.Painter[Paint]; }; image: Graphics.ImageRef _ NIL; AISName: Rope.Text _ "AISTemp$"; otherAISName: Rope.Text _ "AISTemp$$"; PingPongNames: PROCEDURE = { temp: Rope.Text _ AISName; AISName _ otherAISName; otherAISName _ temp; }; StoreAIS: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; fileName: ROPE _ PopRope[f]; map: Wordmap _ wordmap[mapNumber]; aisFile: AIS.FRef; aisWindow: AIS.WRef; raster: AIS.RasterPart; raster.scanCount _ map.side; raster.scanLength _ map.side; raster.scanMode _ rd; raster.bitsPerPixel _ 8; raster.linesPerBlock _ -1; raster.paddingPerBlock _ 0; aisFile _ AIS.CreateFile[name: LOOPHOLE[fileName], raster: @raster, overwrite: TRUE]; aisWindow _ AIS.OpenWindow[aisFile]; FOR i: NAT IN [0..map.side) DO FOR j: NAT IN [0..map.side) DO sample: INT _ map[i*map.side+j]; sample _ MAX[0, MIN[map.unit, sample]]; AIS.WriteSample[aisWindow, 255 - 255*sample/map.unit, i, j]; ENDLOOP ENDLOOP; AIS.CloseWindow[aisWindow]; AIS.CloseFile[aisFile]; }; DrawMap: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; aisFile: AIS.FRef; aisWindow: AIS.WRef; raster: AIS.RasterPart; raster.scanCount _ map.side; raster.scanLength _ map.side; raster.scanMode _ rd; raster.bitsPerPixel _ 8; raster.linesPerBlock _ -1; raster.paddingPerBlock _ 0; aisFile _ AIS.CreateFile[name: LOOPHOLE[AISName], raster: @raster, overwrite: TRUE]; aisWindow _ AIS.OpenWindow[aisFile]; FOR i: NAT IN [0..map.side) DO FOR j: NAT IN [0..map.side) DO sample: INT _ map[i*map.side+j]; sample _ MAX[0, MIN[map.unit, sample]]; AIS.WriteSample[aisWindow, 255 - 255*sample/map.unit, i, j]; ENDLOOP ENDLOOP; AIS.CloseWindow[aisWindow]; AIS.CloseFile[aisFile]; image _ GraphicsOps.NewAisImage[LOOPHOLE[AISName]]; PingPongNames[]; -- to fool the cache in CGAISImageImpl. ReDrawMap[f]; }; ReDrawMap: PROCEDURE [f: Frame] = { Paint: PROCEDURE [context: Graphics.Context] = { Graphics.DrawImage[self: context, image: image]; }; TJaMGraphics.Painter[Paint]; }; BitImageContext: PROCEDURE RETURNS[Graphics.Context] = { bitImageContext _ GraphicsOps.NewContextFromBitmap[bitImage]; RETURN [bitImageContext]; }; UseBitmap: PROCEDURE [f: Frame] = { TJaMGraphicsContexts.AddContext[f, BitImageContext, $BitTunerCmds, TRUE, TRUE]; TJaMGraphicsContexts.DisableViewer[f]; }; UseScreen: PROCEDURE [f: Frame] = { TJaMGraphicsContexts.DisableContext[f, $BitTunerCmds]; TJaMGraphicsContexts.EnableViewer[f]; }; GetBit: PROCEDURE [f: Frame] = {ENABLE Runtime.BoundsFault => CONTINUE; x, y: NAT; bit: NAT _ 0; y _ JaMOps.PopInteger[f.opstk]; x _ JaMOps.PopInteger[f.opstk]; bit _ bitImageDescriptor[bitImage.height-1-y][x]; JaMOps.PushInteger[f.opstk, bit]; }; PutBit: PROCEDURE [f: Frame] = {ENABLE Runtime.BoundsFault => CONTINUE; x, y: NAT; bit: NAT _ JaMOps.PopInteger[f.opstk]; y _ JaMOps.PopInteger[f.opstk]; x _ JaMOps.PopInteger[f.opstk]; bitImageDescriptor[bitImage.height-1-y][x] _ bit; }; LoadFromBitmap: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap; index: NAT _ 0; IF wordmap[mapNumber] = NIL OR wordmap[mapNumber].side # bitImage.width THEN wordmap[mapNumber] _ NewWordmap[bitImage.width]; map _ wordmap[mapNumber]; map.unit _ 65536; FOR i: NAT IN [0..map.side) DO FOR j: NAT IN [0..map.side) DO map[index] _ bitImageDescriptor[i][j]*map.unit; index _ index + 1; ENDLOOP ENDLOOP }; Div2: PROCEDURE [a: INT] RETURNS [b: INT] = INLINE { b _ LOOPHOLE[LongNumberDiv2[LOOPHOLE[a]]] }; LongNumberDiv2: PROCEDURE [a: Inline.LongNumber] RETURNS [b: Inline.LongNumber] = INLINE { b.highbits _ Inline.BITSHIFT[a.highbits, -1] + Inline.BITAND[a.highbits, 100000B]; b.lowbits _ Inline.BITSHIFT[a.lowbits, -1] + Inline.BITSHIFT[a.highbits, 15]; }; ConvolveLeft: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; index: NAT _ 0; side: NAT _ map.side; limit: NAT _ side-1; FOR i: NAT IN [0..side) DO p: LONG POINTER TO INT _ @map[index]; FOR j: NAT IN [0..limit) DO p^ _ Div2[p^ + (p+SIZE[INT])^]; p _ p+SIZE[INT]; ENDLOOP; index _ index + side; ENDLOOP; }; ConvolveUp: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; index: NAT _ 0; side: NAT _ map.side; delta: NAT _ SIZE[INT]*side; FOR i: NAT IN [0..side-1) DO p: LONG POINTER TO INT _ @map[index]; FOR j: NAT IN [0..side) DO p^ _ Div2[p^ + (p+delta)^]; p _ p+SIZE[INT]; ENDLOOP; index _ index + side; ENDLOOP; }; ConvolveRight: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; index: NAT _ map.length; side: NAT _ map.side; FOR i: NAT DECREASING IN [0..side) DO p: LONG POINTER TO INT _ @map[index-1]; FOR j: NAT DECREASING IN [1..side) DO p^ _ Div2[p^ + (p-SIZE[INT])^]; p _ p-SIZE[INT]; ENDLOOP; index _ index - side; ENDLOOP; }; ConvolveDown: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; index: NAT _ map.length; side: NAT _ map.side; delta: NAT _ SIZE[INT]*side; FOR i: NAT DECREASING IN [1..side) DO p: LONG POINTER TO INT _ @map[index-1]; FOR j: NAT DECREASING IN [1..side) DO p^ _ Div2[p^ + (p-delta)^]; p _ p-SIZE[INT]; ENDLOOP; index _ index - side; ENDLOOP; }; Copy: PROCEDURE [f: Frame] = { source: NAT _ JaMOps.PopInteger[f.opstk]; dest: NAT _ JaMOps.PopInteger[f.opstk]; destMap: Wordmap _ wordmap[dest]; sourceMap: Wordmap _ wordmap[source]; IF destMap = NIL OR destMap.side # sourceMap.side THEN destMap _ wordmap[dest] _ NewWordmap[sourceMap.side]; destMap.unit _ sourceMap.unit; FOR index: NAT IN [0..sourceMap.length) DO destMap[index] _ sourceMap[index]; ENDLOOP; }; Add: PROCEDURE [f: Frame] = { source: NAT _ JaMOps.PopInteger[f.opstk]; dest: NAT _ JaMOps.PopInteger[f.opstk]; destMap: Wordmap _ wordmap[dest]; sourceMap: Wordmap _ wordmap[source]; IF destMap.unit # sourceMap.unit OR destMap.side # sourceMap.side THEN ERROR; FOR index: NAT IN [0..sourceMap.length) DO destMap[index] _ destMap[index] + sourceMap[index]; ENDLOOP; }; Subtract: PROCEDURE [f: Frame] = { source: NAT _ JaMOps.PopInteger[f.opstk]; dest: NAT _ JaMOps.PopInteger[f.opstk]; destMap: Wordmap _ wordmap[dest]; sourceMap: Wordmap _ wordmap[source]; IF destMap.unit # sourceMap.unit OR destMap.side # sourceMap.side THEN ERROR; FOR index: NAT IN [0..sourceMap.length) DO destMap[index] _ destMap[index] - sourceMap[index]; ENDLOOP; }; AddShifted: PROCEDURE [f: Frame] = { scale: REAL _ JaMOps.PopReal[f.opstk]; deltaY: INTEGER _ JaMOps.PopInteger[f.opstk]; deltaX: INTEGER _ JaMOps.PopInteger[f.opstk]; source: NAT _ JaMOps.PopInteger[f.opstk]; dest: NAT _ JaMOps.PopInteger[f.opstk]; destMap: Wordmap _ wordmap[dest]; sourceMap: Wordmap _ wordmap[source]; index: NAT _ 0; IF destMap.unit # sourceMap.unit THEN ERROR; FOR i: NAT IN [0..sourceMap.side) DO IF i-deltaY IN [0..destMap.side) THEN { row: NAT _ (i-deltaY)*destMap.side; FOR j: NAT IN [0..sourceMap.side) DO IF j+deltaX IN [0..destMap.side) THEN destMap[row+j+deltaX] _ destMap[row+j+deltaX] + Real.RoundLI[sourceMap[index]*scale]; index _ index + 1; ENDLOOP; } ENDLOOP; }; SubSample: PROCEDURE [f: Frame] = { scaleDownFactor: NAT _ JaMOps.PopInteger[f.opstk]; source: NAT _ JaMOps.PopInteger[f.opstk]; dest: NAT _ JaMOps.PopInteger[f.opstk]; sourceMap: Wordmap _ wordmap[source]; destMap: Wordmap _ NewWordmap[sourceMap.side/scaleDownFactor]; destMap.unit _ sourceMap.unit; FOR i: NAT IN [0..destMap.side) DO FOR j: NAT IN [0..destMap.side) DO destMap[destMap.side*i+j] _ sourceMap[(sourceMap.side*i+j)*scaleDownFactor]; ENDLOOP; ENDLOOP; }; Biggest: PROCEDURE [f: Frame] = { mapno: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapno]; max: INT _ FIRST[INT]; besti, bestj: NAT; index: NAT _ 0; FOR i: NAT IN [0..map.side) DO FOR j: NAT IN [0..map.side) DO IF map[index] > max THEN {max _ map[index]; besti _ i; bestj _ j}; index _ index + 1; ENDLOOP; ENDLOOP; JaMOps.PushInteger[f.opstk, bestj]; JaMOps.PushInteger[f.opstk, map.side-1-besti]; }; Abs: PROCEDURE [f: Frame] = { mapno: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapno]; FOR index: NAT IN [0..map.length) DO map[index] _ ABS[map[index]]; ENDLOOP; }; Sqr: PROCEDURE [f: Frame] = { mapno: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapno]; FOR index: NAT IN [0..map.length) DO int: INT _ map[index]; map[index] _ int*int/map.unit; ENDLOOP; }; Scale: PROCEDURE [f: Frame] = { scale: REAL _ JaMOps.PopReal[f.opstk]; mapno: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapno]; FOR index: NAT IN [0..map.length) DO map[index] _ Real.RoundLI[map[index]*scale]; ENDLOOP; }; Threshold: PROCEDURE [f: Frame] = { threshold: REAL _ JaMOps.PopReal[f.opstk]; mapno: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapno]; t: INT _ Real.RoundLI[map.unit*threshold]; FOR index: NAT IN [0..map.length) DO map[index] _ IF map[index] > t THEN map.unit ELSE 0; ENDLOOP; }; Clip: PROCEDURE [f: Frame] = { max: REAL _ JaMOps.PopReal[f.opstk]; min: REAL _ JaMOps.PopReal[f.opstk]; mapno: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapno]; imax: INT _ Real.RoundLI[map.unit*max]; imin: INT _ Real.RoundLI[map.unit*min]; FOR index: NAT IN [0..map.length) DO map[index] _ MAX[imin, MIN[imax, map[index]]]; ENDLOOP; }; Mask: PROCEDURE [f: Frame] = { source: NAT _ JaMOps.PopInteger[f.opstk]; dest: NAT _ JaMOps.PopInteger[f.opstk]; destMap: Wordmap _ wordmap[dest]; sourceMap: Wordmap _ wordmap[source]; IF destMap.unit # sourceMap.unit OR destMap.side # sourceMap.side THEN ERROR; FOR index: NAT IN [0..sourceMap.length) DO IF sourceMap[index] = 0 THEN destMap[index] _ 0; ENDLOOP; }; Fixate: PROCEDURE [f: Frame] = { max: REAL _ JaMOps.PopReal[f.opstk]; center: REAL _ JaMOps.PopReal[f.opstk]; min: REAL _ JaMOps.PopReal[f.opstk]; imageno: NAT _ JaMOps.PopInteger[f.opstk]; maskno: NAT _ JaMOps.PopInteger[f.opstk]; image: Wordmap _ wordmap[imageno]; mask: Wordmap _ wordmap[maskno]; imax: INT _ Real.RoundLI[image.unit*max]; icenter: INT _ Real.RoundLI[image.unit*center]; imin: INT _ Real.RoundLI[image.unit*min]; IF image.side # mask.side THEN ERROR; FOR index: NAT IN [0..image.length) DO sample: INT _ image[index]; IF mask[index]#0 AND imin <= sample AND sample <= imax THEN { image[index] _ icenter; mask[index] _ 0; } ENDLOOP; }; Twiddle: PROCEDURE [f: Frame] = { max: REAL _ JaMOps.PopReal[f.opstk]; min: REAL _ JaMOps.PopReal[f.opstk]; unit: REAL _ JaMOps.PopReal[f.opstk]; imageno: NAT _ JaMOps.PopInteger[f.opstk]; changeno: NAT _ JaMOps.PopInteger[f.opstk]; change: Wordmap _ wordmap[changeno]; image: Wordmap _ wordmap[imageno]; imax: INT _ Real.RoundLI[change.unit*max]; imin: INT _ Real.RoundLI[change.unit*min]; iunit: INT _ Real.RoundLI[change.unit*unit]; IF image.side # change.side THEN ERROR; FOR index: NAT IN [0..image.length) DO IF change[index]<=imin THEN { image[index] _ 0; }; IF change[index]>=imax THEN { image[index] _ iunit; }; ENDLOOP; }; Histogram: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; count: ARRAY [0..256] OF INT; Paint: PROCEDURE [context: Graphics.Context] = { FOR index: NAT IN [0..256] DO Graphics.DrawBox[context, [index, 0, index+1, count[index]]]; ENDLOOP; }; FOR index: NAT IN [0..256] DO count[index] _ 0; ENDLOOP; FOR index: NAT IN [0..map.length) DO sample: INT _ MAX[0, MIN[256, map[index]*256/map.unit]]; count[sample] _ count[sample] + 1; ENDLOOP; TJaMGraphics.Painter[Paint]; }; Statistics: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; min: INT _ LAST[INT]; max: INT _ FIRST[INT]; sum: INT _ 0; unit: REAL _ map.unit; FOR index: NAT IN [0..map.length) DO sample: INT _ map[index]; min _ MIN[min, sample]; max _ MAX[max, sample]; sum _ sum + sample; ENDLOOP; JaMOps.PushReal[f.opstk, min/unit]; JaMOps.PushReal[f.opstk, max/unit]; JaMOps.PushReal[f.opstk, sum/(unit*map.length)]; }; SumOfSquares: PROCEDURE [f: Frame] = { mapNumber: NAT _ JaMOps.PopInteger[f.opstk]; map: Wordmap _ wordmap[mapNumber]; sumsqr: REAL _ 0; unit: REAL _ map.unit; FOR index: NAT IN [0..map.length) DO realSample: REAL _ map[index]/unit; sumsqr _ sumsqr + realSample*realSample; ENDLOOP; JaMOps.PushReal[f.opstk, sumsqr]; }; Wordmap: TYPE = REF WordmapRec; WordmapRec: TYPE = RECORD[unit: INT _ 1, side: NAT, words: SEQUENCE length: NAT OF INT]; NewWordmap: PROCEDURE [side: NAT] RETURNS [wordmap: Wordmap] = { wordmap _ NEW[WordmapRec[side*side]]; wordmap.side _ side; }; wordmap: ARRAY [0..9] OF Wordmap; bitImage: GraphicsOps.BitmapRef; bitImageDescriptor: BitmapDescriptor; bitImageContext: Graphics.Context; BitmapDescriptor: PUBLIC TYPE = REF READONLY BitmapDescriptorRec; BitmapDescriptorRec: PUBLIC TYPE = RECORD[ bitmapRef: GraphicsOps.BitmapRef, lines: SEQUENCE height: NAT OF LONG DESCRIPTOR FOR PACKED ARRAY OF [0..1] ]; DescriptorFor: PUBLIC PROCEDURE [bitmap: GraphicsOps.BitmapRef] RETURNS [BitmapDescriptor] = { bitmapDescriptor: REF BitmapDescriptorRec _ NEW[BitmapDescriptorRec[bitmap.height]]; raster: NAT _ bitmap.raster; p: LONG POINTER _ LOOPHOLE[bitmap.base]; IF p=NIL THEN [base: p, raster: raster] _ CGScreen.Bits[]; FOR i:NAT IN [0..bitmap.height) DO bitmapDescriptor[i] _ DESCRIPTOR[p, bitmap.width]; p _ p + raster; ENDLOOP; bitmapDescriptor.bitmapRef _ bitmap; RETURN[bitmapDescriptor]; }; DescBase: PUBLIC PROCEDURE [d: LONG DESCRIPTOR FOR PACKED ARRAY OF [0..1]] RETURNS [LONG POINTER] = {RETURN[BASE[d]]}; DescLength: PUBLIC PROCEDURE [d: LONG DESCRIPTOR FOR PACKED ARRAY OF [0..1]] RETURNS [INT] = {RETURN[LENGTH[d]]}; <> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.AllocateBitmap", AllocateBitmap]; << -> . Allocates a size x size bitmap>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.DrawBitmap", DrawBitmap]; <<-> . Draws the bitmap>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.StoreAIS", StoreAIS]; << -> . Saves the map in an AIS file>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.DrawMap", DrawMap]; << -> . Draws the map>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.ReDrawMap", ReDrawMap]; <<-> . redisplays the last image shown with DrawMap>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.GetBit", GetBit]; << -> . Gets a bit out of the bitmap>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.PutBit", PutBit]; << -> . Puts a bit into the bitmap>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.ConvolveLeft", ConvolveLeft]; JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.ConvolveRight", ConvolveRight]; JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.ConvolveUp", ConvolveUp]; JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.ConvolveDown", ConvolveDown]; << -> . Simple neighbor-averaging convolutions>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Copy", Copy]; << -> . Copies the image>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.LoadFromBitmap", LoadFromBitmap]; << -> . Makes a map from the bitmap>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.UseBitmap", UseBitmap]; <<-> . Makes graphics ops go to the bitmap.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.UseScreen", UseScreen]; <<-> . Makes graphics ops go to the screen.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Add", Add]; << -> . Adds corresponding samples.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Subtract", Subtract]; << -> . dest _ dest - source.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.AddShifted", AddShifted]; << -> . Takes map from source, moves it by (deltaX, deltaY), scales each element, and adds the image to dest.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.SubSample", SubSample]; << -> . Extracts every kth sample of source to make dest >> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Biggest", Biggest]; << -> . Finds coordinates of largest sample.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Abs", Abs]; << -> . Replaces each sample by its absolute value.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Sqr", Sqr]; << -> . Replaces each sample by its square.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Scale", Scale]; << -> . Multiplies each sample by scale.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Threshold", Threshold]; << -> . Makes a binary image based on the threshold.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Clip", Clip]; << -> . Clips the samples to lie in the given range.>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Mask", Mask]; << -> . Forces dest to 0 whereever source is 0. >> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Histogram", Histogram]; << -> . >> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Fixate", Fixate]; << -> .>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Twiddle", Twiddle]; <> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.Statistics", Statistics]; << -> .>> JaMOps.RegisterExplicit[JaMOps.defaultFrame, "bt.SumOfSquares", SumOfSquares]; << -> .>> END.