Heading:
Printing Device File Format
Page Numbers: Yes X: 527 Y: 10.5"
Inter-Office Memorandum
ToInterpress NotebookDateMarch 3, 1983
FromKen Pier and Bob SproullLocationPalo Alto
SubjectPrinting Device File FormatOrganizationPARC/ISL
XEROX
Filed on: [maxc]<PrintingDocs>PDFormat.memo & .press
1. Introduction
This memo describes the format of printing device (PD) files. A PD file encodes a series of low-level imaging commands that are used to create a binary image that is then printed on a printing device; a PD file is similar in concept to "bandslists" in [2]. The interpretation of the imaging commands is device-independent, but the way in which the resulting binary image is presented on the device is device-dependent.
An Alto implementation of a PD interpreter is able to create images on a number of different ROS devices [1]. Although this particular implementation builds a full image buffer on a large disk file, it is possible to interpret PD files on-the-fly as the image is being formed.
2. Coordinate system
Locations on the image are measured in a device-dependent coordinate system. The two axis dimensions are labeled s and f. The s, or slow, direction, is measured along the direction of paper transport, i.e., locations with greater values of s are imaged after locations with lesser values of s. Most printers Xerox builds have the s direction oriented along the narrow edge of an 8|X11 inch piece of paper ("landscape scanning"), i.e., it is oriented left-to-right on this piece of paper when you are holding it in the normal reading orientation. The f, or fast, direction is chosen so that sXf points toward the viewer of the image. On this piece of paper, f points vertically, from bottom to top. The origin of the coordinate system is chosen so that it lies on the medium and so that all points on the medium are measured with non-negative values of s and f. On this page, the origin is at the lower-left corner; s points to the right and f points up. On a display ("portrait scanning"), the origin is at the upper-left corner, s points down and f points to the right.
The coordinate s can be thought of as addressing a scan-line and f the pixels along a scan-line. We try to avoid using the terms width and height because these are tied to the final image and the orientation in which it is held rather than to the raster imaging scheme; we speak instead of fSize and sSize. Note that the f direction may or may not indicate the order in which pixels are laid down on the image.
The Pimlico and Puffin color printers and the MIG use portrait scanning.
The entire image size is determined by the two quantities imageSSize and imageFSize. A coordinate (s,f) lies on the image iff 0<s̈¿imageSSize and 0<f̈¿imageFSize.
The resolution of the device is determined by two numbers, sResolution and fResolution, which give the number of raster points per inch along the s and f directions, respectively.
A band is a region of the image bandSSize scan-lines wide. That is, the coordinate s lies in band b iff bandSSize*b<s̈¿bandSSize*(b+1). PD files must be written with information sorted into band order, i.e., commands that apply to band 0 come first, followed by commands that apply to band 1, and so on.
3. Imaging model
Most of the commands in a PD file modify the raster image being built up to be sent to the printer. This section describes how the modifications are made. We use the notation M for mask data, C for color data, and I for the image data being built up; conceptually, these are all two-dimensional binary arrays that cover the image. At the beginning of each page, I←ALL[0], i.e., the value of each pixel in I is set to 0. Imaging commands in the PD file then make modifications to I. After all modifications have been made, the image may be printed. Ink will be deposited for each pixel in the image I that has a value of 1, and no ink will be deposited where the value is 0.
The changes made to I by an imaging command are governed by the mask M, the color C, and the imaging-model-type, T. The mask M, which is specified by a mask command, conceptually covers the entire image, and has a value 1 for those pixels "inside" the mask and 0 for those points outside the mask. Similarly, the color C covers the entire image; the interpretation of the values in C depends on T. If T=opaque, then pixels in C with a value of 1 will correspond to places where ink should appear in the image, and pixels with value of 0 to places where no ink should appear. If T=transparent, pixels in C with a value of 1 will correspond to places where ink should appear and those with value 0 to places where the page image should remain unmodified, irrespective of the mask values. This mode is named transparent because it allows images laid down previously to show through a color pattern.
More formally, the operation invoked by an imaging command that specifies mask M, C, and imaging-model-type is T is:
if T=opaque then I←(I&nM)V(C&M) else IIV(C&M)
4. Interpreter modes
The interpreter may be operated in one of two modes, determined by the creator of the PD file. These modes are:
1. bandMode. The PD file gives commands for building up each band of the image, entirely independently of other bands. The commands in the file that apply to a given band are followed by an endBand command to signal that the band is finished and may be printed.
2. leftOverMode. The PD file contains imaging commands for building up each band of the image, but a command may specify a modification to the image that extends to subsequent bands beyond the initial one. The PD interpreter is responsible for maintaining "leftover lists" to remember necessary information about objects begun in one band that carry over to subsequent bands. Conceptually, the leftover list contains a triple (M, C, T, P) that records the mask, color, imaging-model type, and priority (see below) of the imaging command that is left over.
In both cases, the information is sorted by band number, i.e., commands that apply to band 0 appear before commands that apply to band 1. Some interpreters may support only bandMode.
When the interpreter is operated in bandMode, an operation called band clipping is performed. Band clipping clips all imaging commands for a band so as to exclude any parts of the modification that lie outside the band.
For example, band clipping allows an imaging command that affects a region 35<s<63 to be included in the imaging commands for a band that extends over 40<s<49. As a consequence, imaging commands in bandMode may have values of s that lie outside the band in question and that are not in sorted order, but band clipping will restrict the modifications to a single band.
In many cases, the order in which commands are executed is important—this is the priority issue, as described in Interpress. The need to preserve priority interacts with the leftOverMode interpreter mode. There is no problem with bandMode, since every operation on the image is specified in the PD file and the order of occurrence in the file will be the order of execution by the interpreter. The problem arises when leftovers are used because the order of execution of leftovers and PD file commands must be determined. To solve this problem, a command named setPriority may be included in PD files to set the priority (modally) of subsequent imaging commands: commands with a larger priority number are executed after commands with lower priorities. Within the sequence of imaging commands for a band recorded in a PD file, priority may not decrease, i.e., commands must be sorted in order of increasing priority. The interpreter is responsible for ordering the processing of PD file entires and leftover entries so as to preserve priority order.
Commands that appear in a PD file are interpreted in order. However, when a setPriority command is encountered, interpretation may switch to the leftover list (or back).
5. Data structures
A PD file is a sequence of 16-bit words, prepared according to a format explained later in the document. In the description of formats, we often make use of Mesa-like structures:
CARD is a 16-bit cardinal. Unless othewise annotated, CARD is assumed.
CARD24 is a 24-bit cardinal.
LONG CARD encodes a 32-bit cardinal as two words, with low-order word appearing first in the file.
An enumerated type such as {noFeedSheet, feedSheet} has as concrete representation a CARD (or field within a CARD) with value 0 corresponding to the first identifier in the enumeration, 1 to the second, etc.
Records are described by surrounding descriptions of their fields with brackets [ ].
All figures are drawn with larger memory addresses nearer the bottom of the page.
Load. The PD file may contain commands that store or read data in an area of the PD interpreter’s memory called the load. This memory is used to hold character masks and color specifications that are referenced repeatedly in a PD file, thus reducing the size of the PD file by using references rather than the actual data. The load is an array of maxLoadWords 16-bit words, with long cardinal addresses i, 0<ï¿maxLoadWords.
There is a storeLoad command available to store data in the load. The state of the load is retained from image to image; storeLoad commands are processed in the order they appear in the PD file. The intent is that the load be set at the beginning of each image, immediately preceding a startImage command (Section 6.2).
It is not recommended to change the contents of the load in the middle of an image. Such a change will work only if the it does not disturb portions of the load that are needed for any subsequent imaging commands, particularly imaging commands that are carried forward by the interpreter using leftovers.
Sample arrays. Several imaging commands make use of a type SampleArray, which represents a rectangular array of binary samples (0 and 1). This type is shown schematically in Figure 2.
SampleArray: [sSize, fSize: CARD, samples: SEQUENCE COMPUTED CARD OF CARD] contains two cardinals giving the size of the array (sSize and fSize), followed by sSize scan-lines, each one of which contains ifSize/16j words of sample data. The array represents the region 0<s̈¿sSize and 0<f̈¿fSize. The first scan-line of sample data is for s=0, the second for s=1, etc. Within a scan-line, the high-order bit of the first word corresponds to f=0, the next-to-high-order bit to f=1, etc. Each scan-line is padded with zeroes to a word boundary.
Tiles. A tile is a sample array that is given a particular location in the image and is tiled to cover the entire image. It is shown schematically in Figure 2.
Tile: [phase, sMin, fMin: CARD, sa: SampleArray]. The sample array sa is repeated to cover the entire image. Origins of the array are at (sMin+i*sa.sSize, fMin+j*sa.fSize+i*phase), for all integers i and j.
Tiles are implemented very efficiently if phase=sMin=fMin=0 and sa.sSize=sa.fSize=16. These are sometimes called "inkwells."
Run Groups. A run group uses a run-length encoding to record binary data.
Run: [fMin: CARD, lastRun: BOOLEAN, fSize: [0..32767]]. The region fMin<f<fMin+fSize−1 contains all 1’s. The boolean lastRun is true if this is the last run on this scan-line.
RunGroup: [sSize: CARD, runs: SEQUENCE COMPUTED CARD OF Run]. A run group contains runs for sSize scan-lines; each scan-line consists of one or more runs ending with a run with the lastRun boolean true.
6. PD File Contents
The overall file structure is illustrated in Figure 3. A PD file begins with a record called the herald. Then each image is described. Each image begins with a startImage command; within each image, endBand commands mark the end of each band. At the end of the file is an endDocument command.
6.1 Herald
The herald contains information used to initialize the interpreter. The fields in the record are (Figure 4):
password: CARD=125252B. The password identifies the file as a PD file. All versions will use this password.
version: CARD. Identifies the version for which this PD file is constructed. This document defines files for which version=1.
deviceCode: CARD. Identifies the device for which this PD file is constructed. Section 7 gives device codes and parameters as of this writing.
sResolution, fResolution: CARD. Resolution of the device in pixels per inch along the s and f directions.
imageSSize, imageFSize: CARD. Total image size assumed by the images in this PD file. These dimensions may not be larger than the device can handle. The PD interpreter never translates an image (e.g., centers it)—the (0, 0) point must always lie at a corner of the page.
bandSSize: CARD. The number of scan-lines in a band; otherwise ignored.
maxLoadWords: LONG CARD. The size of the memory area that must be allocated to the load.
copies: CARD. The number of copies of the file to print.
The PD interpreter will examine the herald to determine whether it can print the file. It may disagree about the properties of the device or it may not be able to accommodate the resources requested (e.g., maxLoadWords). For any of these reasons, the interpreter may reject the file.
6.2 Control commands
Control commands delineate portions of a PD file and set several state variables that control the interpretation of imaging commands (curC, curT, and curP). At the beginning of each band, curC := ALL[1], curT := opaque, and curP := 0.
startImagë[interpreterMode: {bandMode, leftOverMode}, feed, strip: {false, true}, tonerColor: [0..16), passBands, nBands, fMinPage, fSizePage: CARD]. The startImage command precedes any imaging commands for an image. It tells the printer whether a new sheet of paper is to be fed to the printer to hold the image, and whether the sheet is to be stripped out of the printer after the image is formed. For all black-and-white printers, feed and strip must be true, but for color printers that take several passes to assemble a multi-colored page, a page will be fed on the first pass and stripped on the last pass. The color of the toner to use for the image is specified by tonerColor:
0Black
1
Cyan
2
Magenta
3
Yellow
The interpreterMode field determines how the interpreter will operate in the image that is starting.
The passBands argument specifies how many initial bands on the page are empty; nBands determines how many bands are to be imaged (some may not have any images in them, of course). The fMinPage and fSizePage arguments specify the range of values of f that encompasses the entire image of the page. These numbers allow the interpreter to allocate smaller band and disk buffers for images. For multiple separations being imaged on the same sheet, all separations should have the same values for these four parameters.
setPriority[priority: CARD24]. This command sets the priority for all subsequent imaging commands, i.e., curP := priority.
setColorInk. This command sets the current color curC := ALL[1], and curT := opaque.
setColorClear. This command sets the current color curC := ALL[0], and curT := opaque.
setColorTile[t: {opaque, transparent}, addr: LONG CARD]. This command sets the current color curC := (the Tile at address addr in the load), and curT := t.
endBand. This control command signals the end of a band. There are nBands such commands in each image.
endDocument. This command signals the end of the document. The PD interpreter ignores any information following this command.
storeLoad̈[firstAddress: LONG CARD, wordCount: CARD, data: WORD [1..wordCount]]. This command causes the data words to be stored in the load, starting with the word whose address relative to the start of the load is firstAddress.
deviceCommand̈[wordCount: CARD, data: WORD [1..wordCount]]. This command cause the data words to be interpreted in a device-dependent way by the printer.
6.3 Imaging commands
There are seven commands that modify the image I being built up:
imagePrimitive={maskSamplesRef, maskRunGroupRef, maskRectangle, maskTrapezoid, maskRunGroup, maskSamples, colorData};
The following paragraphs define the interpretation of each mask type and the parameters it requires. Unless otherwise noted, C=curC, T=curT, and P=curP.
maskRectangle[sMin, sSize, fMin, fSize: CARD]. M is set to 1 for (s,f) in the region sMin<s<sMin+sSize−1, fMinFirst<f<fMinFirst+fSizeFirst−1; M is zero everywhere else.
maskTrapezoid[sMin, sSize, fMin, fSize, fMinLast, fSizeLast: CARD]. M is set to 1 for (s,f) in the region bounded by the trapezoid whose vertices are at (sMin, fMin), (sMin, fMin+fSize−1), (sMin+sSize−1, fMinLast+fSizeLast−1), (sMin+sSize−1, fMinLast); M is zero everywhere else.
The interpolation scheme used by maskTrapezoid must be known precisely, in case the creator of a PD file wants to predict precisely which pixels will be inside the mask. The inside of the mask is those pixels (s,f) such that sMin<s<sMin+sSize−1 and b(s)<f̈¿t(s), where:
b(s)=fMin+(fMinLastfMin)*(ssMin)/(sSize−1)
t(s)=fMin+fSize+(fMinLast+fSizeLastfMinfSize)*(ssMin)/(sSize−1).
maskRunGroup[sMin: CARD, rg: RunGroup]. M is set to 1 in the region sMin<s<sMin+rg.sSize−1, wherever specified by a run in rg.
maskSamples[sMin, fMin: CARD, a: SampleArray]. M is obtained from the sampled data, as described in Section 4, in the region sMin<s<sMin+a.sSize−1, fMin<f<fMin+a.fSize−1.
maskRunGroupRef[addr: CARD24, sMin, fMin: CARD]. Like maskRunGroup, but the run group itself is located at address addr in the load. The value of fMin is added to the fMin’s in the run group. To make a compact file, only 24 bits of addr are put in the file, and in a funny order.
maskSamplesRef[addr: CARD24, sMin, fMin: CARD]. Like maskSamples, but the run group itself is located at address addr in the load. To make a compact file, only 24 bits of addr are put in the file, and in a funny order.
colorSamples[sMin, fMin: CARD, a: SampleArray]. C is obtained from the sampled data, as described in Section 4, in the region sMin<s<sMin+a.sSize−1, fMin<f<fMin+a.fSize−1. M is 1 in the region sMin<s<sMin+a.sSize−1, fMin<f<fMin+a.fSize−1, and 0 elsewhere. T is opaque.
Warning: Leftovers are not maintained for maskRunGroup, maskSamples, or colorSamples because they require variable-length data in the leftover list. To use these forms, the PD file must contain proper mask commands in each band. However, the load-reference forms maintain proper leftovers.
6.4 Encoding the commands
The imaging and control commands are encoded with a view to reducing the size of the most common PD files. Many of the commands have arguments, which are encoded in records immediately following the one-word command descriptor. The data fields are described in Section 6, and Figures 5−7 show how the fields are laid out. Since character instances appear very frequently, the formats for maskRunGroupRef and maskSamplesRef are short.
7. Devices
At present, the only way to print PD files is with the Alto program PDPrint [1]. It will print on a variety of devices, listed below. If this program is run on a wide-bodied Alto (extended memory), maxLoadWords cannot exceed 60,000. If the program is run on a conventional Alto II, maxLoadWords is restricted to 20,000.
The following paragraphs describe the properties of various printing devices that can be controlled by PD files. Note
Raven (Quoth). Device code=1. Landscape. sResolution=fResolution=300, imageSSize=2550, imageFSize=3300, 16<bandSSize<100.
Hornet (Stinger). Device code=2. Landscape. sResolution=fResolution=384, imageSSize=3264, imageFSize=4224, 16<bandSSize<100.
Gnat. Device code=3. Landscape. xx
MIG. Device code=4. Portrait. xx
ReticleMaker. Device code=5. Portrait. xx
Puffin (Lilac). Device code=6. Portrait. sResolution=fResolution=384, imageSSize=4224, imageFSize=3264, bandSSize=16.
References
[1] "PD Printer Operation", March 30, 1983. Filed on [maxc]<printingdocs>pdprintops.press.
[2] O. Sperber, J. Kellman, R.E. Joiner, and S.R. Dashiell, "A VLSI based Image Generation Architecture for Low End Electronic Printing," November 1982. RBG/ED/EED/ESD