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: ATOMNIL]
         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.