DIRECTORY Basics USING[BYTE], Terminal USING[Virtual], Atom USING[PropList], Rope USING[ROPE], Imager USING[Context, Rectangle], SampleMapOps USING[SubMap, Buffer]; Pixels: CEDAR DEFINITIONS ~ BEGIN BYTE: TYPE ~ Basics.BYTE; -- parts of a pixel will not exceed 8 bits in the forseeable future Extent: TYPE ~ RECORD[x, y, w, h: NAT]; SampleSet: TYPE ~ SampleMapOps.Buffer; SampleSetSequence: TYPE ~ RECORD[SEQUENCE length: NAT OF SampleSet]; SubMap: TYPE ~ RECORD[ subMap: SampleMapOps.SubMap, df: NAT _ 1]; SubMapSequence: TYPE ~ RECORD[SEQUENCE length: NAT OF SubMap]; PixelBuffer: TYPE ~ RECORD[ width: NAT _ 0, -- width, in pixels, of pixel grid height: NAT _ 0, -- height, in pixels, of pixel grid samplesPerPixel: NAT _ 0, -- number of samples representing each pixel (eg. RGB) pixels: REF SubMapSequence _ NIL, -- The bits. Each SubMap represents one sample from a pixel. Where an alpha buffer or depth buffer is used, its location is stored in the props under $Alpha or $Depth. props: Atom.PropList _ NIL ]; PixelsError: SIGNAL [reason: ErrorDesc]; ErrorDesc: TYPE ~ RECORD [code: ATOM, explanation: Rope.ROPE]; XfmMapPlace: PROC [ map: SubMap, x, y: INTEGER ] RETURNS [newX, newY: INTEGER]; ByteAvrgWgtd: PROC[ b1, b2, wgt: BYTE ] RETURNS[ bOut: BYTE ]; SumLessProd: PROC[ b1, b2: BYTE ] RETURNS[ bOut: BYTE ]; GetSampleSet: PROC[size: NAT] RETURNS[SampleSet]; Create: PROC [width, height: NAT, pixelSizes: SampleSet] RETURNS[PixelBuffer]; GetFromImagerContext: PROC [context: Imager.Context, alpha, depth: BOOLEAN] RETURNS[PixelBuffer, Imager.Rectangle]; GetFromTerminal: PROC [vt: Terminal.Virtual, alpha, depth: BOOLEAN] RETURNS[PixelBuffer]; TerminalFromBuffer: PROC [buf: PixelBuffer] RETURNS[vt: Terminal.Virtual]; ImagerContextFromBuffer: PROC [buf: PixelBuffer, type: ATOM _ NIL] RETURNS[ctx: Imager.Context]; Fill: PROC [buf: PixelBuffer, pixel: SampleSet _ NIL]; Transfer: PROC [dstBuf, srcBuf: PixelBuffer]; Copy: PROC [ destination, source: PixelBuffer, destArea, srcArea: Extent, op: ATOM _ $Write ]; ShowOnImagerContext: PROC [context: Imager.Context, buf: PixelBuffer]; GetPixel: PROC [buf: PixelBuffer, x, y: NAT, pixel: SampleSet _ NIL] RETURNS[ SampleSet ]; PutPixel: PROC [ buf: PixelBuffer, x, y: NAT, pixel: SampleSet ]; GetScanSeg: PROC [buf: PixelBuffer, x, y, length: NAT, pixels: REF SampleSetSequence _ NIL] RETURNS[ REF SampleSetSequence ]; PutScanSeg: PROC [ buf: PixelBuffer, x, y, length: NAT, pixels: REF SampleSetSequence, op: ATOM _ $Write ]; PixelOp: PROC [ buf: PixelBuffer, area: Extent, pixel: SampleSet, op: ATOM _ $Write ]; GetValue: PROC [buf: PixelBuffer, x, y: NAT, map: NAT _ 0] RETURNS[ value: CARDINAL ]; PutValue: PROC [ buf: PixelBuffer, x, y: NAT, value: CARDINAL, map: NAT _ 0 ]; ValueOp: PROC [ buf: PixelBuffer, area: Extent, value: CARDINAL, map: NAT _ 0, op: ATOM _ $Write ]; END. ΠPixels.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Frank Crow, June 5, 1986 1:24:01 pm PDT Basic operations on two-dimensional arrays of pixels. A pixel consists of an arbitrary number of values (samples) addressed at the same position. A pixel is supposed to represent the information behind a displayed spot, not all of which is necessarily visible to the viewer. One typical pixel format consists of 4 samples, one each for alpha, red, green, and blue. Type Definitions REF RECORD [length: NAT, samples: SEQUENCE maxLength: NAT OF CARDINAL];; extended SubMap, df is distance (in samples) between samples Utility Procedures Creation Operations Allocates bits and builds PixelBuffer record with default procedures. PixelSizes allows arbitrary collections of bits to be used as pixels Forces pixel buffer onto Imager context in those circumstances where it is possible, stores REF to imager context on PixelBuffer.props Makes pixel buffer out of terminal color display, if there is one PixelBuffer Operations For getting terminal when needed for locking, etc. Allows imager calls to act on your pixels understood types are: $Dithered, $Mapped, $Grey, $Dorado24 Fill pixels with specified pixel value, default pixel value (pixel = NIL) clears to zero Copies one PixelBuffer into another, doing the "right thing" about non-visible buffers Copies using the specified source and destination rectangles Puts pixels from displayMemory onto supplied context using Imager calls Pixel operations In the following, a SampleSet is assumed to map one byte into one SubMap. Those in a hurry can avoid allocates by caching "pixel" (the 4th argument) Standard ops include: $AND = bitwise AND $OR = bitwise OR $XOR = bitwise XOR $Write = replace previous contents with new pixel (default) $WriteUnder = blend behind previously written pixels (using alpha buffer) $WriteOver = blend in front of previously written pixels (using alpha buffer) Visible value operations In the following, the Client specifies which submap is targeted, and gains speed thereby. Standard ops are: $AND = bitwise AND $OR = bitwise OR $XOR = bitwise XOR $Write = replace previous contents with new pixel (default) Κm˜head3šΟb ™ Jšœ Οmœ7™BJ™(J™ςJ™šΟk ˜ JšœŸœŸœ˜Jšœ Ÿœ ˜Jšœ Ÿœ ˜Jšœ ŸœŸœ˜Jšœ Ÿœ˜$JšœŸœ˜$——head2šœŸœŸ ˜JšœŸ˜—š™IašŸœŸœ ŸœΟcC˜^JšœŸœŸœ Ÿœ˜'šœ Ÿœ˜&MšŸœŸœ Ÿœ Ÿœ ŸœŸœŸœ™H—Jš œŸœŸœŸœ ŸœŸœ ˜DšœŸœŸœ#Ÿœ˜AJšœ=™=—Jš œŸœŸœŸœ ŸœŸœ ˜?šœ ŸœŸœ˜JšœŸœ  $˜8JšœŸœ  #˜9JšœŸœ  6˜SJšœŸœŸœ Οi ˜ΚJšœŸ˜Jšœ˜—Mšœ Ÿœ˜(Jš œ ŸœŸœŸœŸœ˜>J˜—š™Mš Οn œŸœŸœŸœŸœ˜OIdefaultš ’ œŸœŸœŸœŸœ˜@Nš ’ œŸœ ŸœŸœŸœ˜8Nš’ œŸœŸœŸœ ˜1—š™unitš’œŸœŸœŸœ˜PNšœ‹™‹—š’œŸœ)Ÿœ Ÿœ ˜|Nšœ†™†—š’œŸœ&Ÿœ Ÿœ˜bN™A—N™—š™š’œŸœŸœ˜JN™2—š ’œŸœŸœŸœŸœ˜lNšœd™d—š’œŸœ'Ÿœ˜6NšœEŸœ™X—š’œŸœ˜-N™W—š’œŸœIŸœ ˜dM™<—š’œŸœ-˜FN™G——š™MšœI™Iš ’œŸœŸœŸœŸœ˜`MšœJ™J—Mš’œŸœŸœ˜AMš’ œŸœ"Ÿœ ŸœŸœŸœŸœ˜ƒMš ’ œŸœ#ŸœŸœŸœ ˜sš’œŸœ>Ÿœ ˜[™M™M™M™M™>M™KM™O——N˜—š™MšœY™YMš ’œŸœŸœŸœŸœ Ÿœ˜VMš ’œŸœŸœ ŸœŸœ˜Nš ’œŸœ*ŸœŸœŸœ ˜j™M™M™M™M™>——N˜—JšŸœ˜—…— ŒΙ