INTERFACE MSImage; IMPORT PSPlot, Rd, PixelWeightTable; TYPE NAT = CARDINAL; LONG = LONGREAL; BYTE = BITS 8 FOR [0..255]; SIGN = [-1..+1]; TYPE T = ARRAY OF ARRAY OF Pixel; (* An Image.T is a function from some subset of the integer lattice to the set of "Pixel" values. If "im" is an Image, "im[y,x]" is the pixel associated with the point "(x,y)". (Note that row [0] is the *bottom* row.) The pixels are assumed to be samples, taken at integer points, of a continuous image with band-limited spectrum. By convention, if element "im[y,x]" does not exist, or is a special "noPixel" value, the image is undefined at the point "(x,y)". *) Pixel = BYTE; Pixels = ARRAY OF Pixel; (* Pixel values are gray levels for now. *) Point = ARRAY [0..1] OF INTEGER; Points = ARRAY OF Point; (* An integer point of the plane: element 0 is X, 1 is Y. *) Size = ARRAY [0..1] OF NAT; (* Dimensions of an image, in pixels: element 0 is width, 1 is height. *) CONST NoPoint = Point{LAST(NAT), LAST(NAT)}; (* A `null' value for a "Point". *) PROCEDURE ReadPGM(rd: Rd.T): REF T; (* Reads a PGM file from "rd" and returns it as an image. Note: row "0" of the result is the *bottom* scanline of the PGM file. *) PROCEDURE GetSize(READONLY im: T): Size; (* Returns the width and height of "im". *) CONST CoarsenRatio = 4; (* The area scaling factor of "Coarsen". *) PROCEDURE Coarsen( READONLY im: T; maxPixel: NAT; noPixel: NAT; maxError: LONG; ): REF T; (* Returns a filtered, reduced and subsampled version of image "im". The images are related by RefinedPoint and CoarsenedSize, below. Pixel values in "[0..maxPixel]" (skipping "noPixel", if it is in that range) are implicitly converted to intensities in "[0 _ 1]", and the same encoding is used for the output image. Any input pixel equals to "noPixel", or outside the image bounds, is assumed to have unknown intensity between 0 and 1. Any output pixel whose value depends on such indeterminate pixels will therefore have a range of possible intensities. If the range is wider than "2*maxError", the outpt pixel is set to "noPixel", otherwise the center of the range is taken as the pixel's intensity. *) PROCEDURE CoarsenedSize(s: Size): Size; (* Given the size "s" of an image "im", returns the size of "Coarsen(im)". *) PROCEDURE RefinedPoint(p: Point): Point; (* If "imLo = Coarsen(imHi)", then point "p" of image "imLo" corresponds to point "RefinedPoint(p)" of image "imHi". AS a special case, "RefinedPoint(NoPoint) = NoPoint". *) PROCEDURE RankFilter( READONLY im: T; READONLY w: PixelWeightTable.T; maxPixel: NAT; noPixel: NAT; maxError: LONG; ): REF T; (* Returns an image where each pixel "p" of "im" has been replaced by its weighted rank in its neighborhood; that is, the sum of the weights for pixels less than "p". The dimensions of "w" must be odd and equal, the center element must be 0, and that wthe other elements must add to 1. *) PROCEDURE Plot(f: PSPlot.File; READONLY im: T; maxPixel: NAT; noPixel: NAT); (* Paints the image "im" on the Postscript file "f". Assumes "f" has already been initialized and is ready for drawing commands. Pixels are painted as unit squares centered at gridpoints; so the user coordinate scale should include the rectangle "[-0.5 _ NX-0.5] x [-0.5 _ NY-0.5]". *) PROCEDURE DistSqr(READONLY u, v: Point): NAT; (* Square of distance between the integer gridpoints "u" and "v". *) PROCEDURE TriAreaX2(READONLY u, v, w: Point): INTEGER; (* The signed area ofthe triangle "u,v,w", times 2 to keep it integer. *) PROCEDURE TriSign(READONLY u, v, w: Point): SIGN; (* Orientation of triangle "u", "v", "w". *) END MSImage.