Pixels.mesa
Copyright © 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.
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
Type Definitions
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;
REF RECORD [length: NAT, samples: SEQUENCE maxLength: NAT OF CARDINAL];;
SampleSetSequence: TYPE ~ RECORD[SEQUENCE length: NAT OF SampleSet];
SubMap:
TYPE ~
RECORD[ subMap: SampleMapOps.SubMap, df:
NAT ← 1];
extended SubMap, df is distance (in samples) between samples
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];
Utility Procedures
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];
Creation Operations
Create:
PROC [width, height:
NAT, pixelSizes: SampleSet]
RETURNS[PixelBuffer];
Allocates bits and builds PixelBuffer record with default procedures. PixelSizes allows arbitrary collections of bits to be used as pixels
GetFromImagerContext:
PROC [context: Imager.Context, alpha, depth:
BOOLEAN]
RETURNS[PixelBuffer, Imager.Rectangle];
Forces pixel buffer onto Imager context in those circumstances where it is possible, stores REF to imager context on PixelBuffer.props
GetFromTerminal:
PROC [vt: Terminal.Virtual, alpha, depth:
BOOLEAN]
RETURNS[PixelBuffer];
Makes pixel buffer out of terminal color display, if there is one
PixelBuffer Operations
TerminalFromBuffer:
PROC [buf: PixelBuffer]
RETURNS[vt: Terminal.Virtual];
For getting terminal when needed for locking, etc.
ImagerContextFromBuffer:
PROC [buf: PixelBuffer, type:
ATOM ←
NIL]
RETURNS[ctx: Imager.Context];
Allows imager calls to act on your pixels understood types are: $Dithered, $Mapped, $Grey, $Dorado24
Fill:
PROC [buf: PixelBuffer, pixel: SampleSet ←
NIL];
Fill pixels with specified pixel value, default pixel value (pixel = NIL) clears to zero
Transfer:
PROC [dstBuf, srcBuf: PixelBuffer];
Copies one PixelBuffer into another, doing the "right thing" about non-visible buffers
Copy:
PROC [ destination, source: PixelBuffer, destArea, srcArea: Extent,
op:
ATOM ← $Write ];
Copies using the specified source and destination rectangles
ShowOnImagerContext:
PROC [context: Imager.Context, buf: PixelBuffer];
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.
GetPixel:
PROC [buf: PixelBuffer, x, y:
NAT, pixel: SampleSet ←
NIL]
RETURNS[ SampleSet ];
Those in a hurry can avoid allocates by caching "pixel" (the 4th argument)
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 ];
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.
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 ];
Standard ops are:
$AND = bitwise AND
$OR = bitwise OR
$XOR = bitwise XOR
$Write = replace previous contents with new pixel (default)
END.