AISFileFormat.mesa
Copyright Ó 1984, 1985, 1986, 1987, 1988, 1992 by Xerox Corporation. All rights reserved.
Doug Wyatt, February 22, 1986 2: 53: 48 pm PST
Michael Plass, February 11, 1988 10:11:44 am PST
DIRECTORY Basics USING [HWORD];
AISFileFormat: CEDAR DEFINITIONS
~ BEGIN
Card16: TYPE ~ Basics.HWORD; -- big-endian 16-bit unsigned number
Int16: TYPE ~ Basics.HWORD; -- big-endian 16-bit signed number
bitsPerAISWord: NAT ~ 16; -- an AIS "word" is 16 bits
wordsPerAISPage: NAT ~ 1024; -- an AIS "page" is 1024 "words"
bytesPerAISWord: NAT ~ bitsPerAISWord/8;
bytesPerAISPage: NAT ~ bytesPerAISWord*wordsPerAISPage;
zero: Basics.HWORD ~ [0, 0];
nil: Basics.HWORD ~ [BYTE.LAST, BYTE.LAST]; -- commonly used for a nil value
passwordValue: Basics.HWORD ~ [hi: 84H, lo: 0AAH]; -- = -31574
AttributeHeader: TYPE ~ MACHINE DEPENDENT RECORD[
password(0:0..15): Card16, -- password, must equal passwordValue
length(0:16..31): Card16 -- length in 16-bit words of attribute section, including this header
length must be a multiple of wordsPerAISPage
];
byteSizeAttributeHeader: NAT ~ BYTES[AttributeHeader];
PartHeader: TYPE ~ MACHINE DEPENDENT RECORD[
type(0:0..5): PartType, -- type of attribute part
lengthHi(0:6..7): [0..4), lengthLo(0:8..15): BYTE
(256*lengthHi+lengthLo) = length of part in 16-bit words, including this one
];
byteSizePartHeader: NAT ~ BYTES[PartHeader];
PartType: TYPE ~ MACHINE DEPENDENT {
nil(0), -- no more parts
raster(1), -- RasterPart follows
placement(2), -- PlacementPart follows
photometry(3), -- PhotometryPart follows
comment(4), -- CommentPart follows
(77B)
};
RasterPart: TYPE ~ MACHINE DEPENDENT RECORD[
scanCount(0:0..15): Card16, -- number of scan lines
scanLength(0:16..31): Card16, -- pixels per scan line
scanDirection(0:32..47): ScanDirection, -- scanning directions
samplesPerPixel(0:48..63): Card16, -- number of samples
codingTypeHi(0:64..71): BYTE, -- currently always 0
codingType(0:72..79): CodingType, -- method of coding
pad(0:80..95): Card16 -- pad to multiple of 32 bits (not in file)
];
byteSizeRasterPart: NAT ~ BYTES[RasterPart]-BYTES[Card16];
ScanDirection: TYPE ~ Card16;
There may not be universal agreement on the interpretation of this value. The AIS documentation disagrees with (at least some versions of) AISFile.d. Fortunately, the two most commonly used values are unambiguous:
3 => pixels go toward the right of the page, scan lines toward the bottom
0, 8 => pixels go toward the top of the page, scan lines toward the right
CodingType: TYPE ~ MACHINE DEPENDENT {
nil(0), -- undefined
uca(1), -- UCACoding folllows
(255)
};
UCACoding: TYPE ~ MACHINE DEPENDENT RECORD[ -- UnCompressedArray
bitsPerSample(0:0..15): Card16, -- number of bits for each sample
wordsPerScanLine(0:16..31): Card16, -- number of 16-bit words per scan line
scanLinesPerBlock(0:32..47): Card16, -- scan lines in each block, nil if no blocks
paddingPerBlock(0:48..63): Card16 -- words of padding at end of block, nil if no blocks
];
byteSizeUCACoding: NAT ~ BYTES[UCACoding];
PlacementPart: TYPE ~ MACHINE DEPENDENT RECORD[
xLeft(0:0..15): Int16, -- position of lower left corner
yBottom(0:16..31): Int16,
xWidth(0:32..47): Int16, -- size of image area on page
yHeight(0:48..63): Int16
];
byteSizePlacementPart: NAT ~ BYTES[PlacementPart];
PhotometryPart: TYPE ~ MACHINE DEPENDENT RECORD[
signalHi(0:0..7): BYTE ¬ 0, -- currently always 0 or 255
signal(0:8..15): SignalType ¬ bw, -- what type of signal is sampled
sense(0:16..31): Card16 ¬ zero, -- larger sample values are lighter if sense=0, else darker
scaleHi(0:32..39): BYTE ¬ 0, -- currently always 0 or 255
scale(0:40..47): ScaleType ¬ nil, -- specifies the conversion between physical and sample values
scaleA(0:48..79), scaleB(0:80..111), scaleC(0:112..143): Value ¬ [zero, zero],
spotTypeHi(0:144..151): BYTE ¬ 0, -- currently always 0 or 255
spotType(0:152..159): SpotType ¬ nil, -- spot type
spotWidth(0:160..175): Card16 ¬ nil, -- in units of 100*(width in pixels)
spotLength(0:176..191): Card16 ¬ nil, -- in units of 100*(length in scanlines)
sampleMin(0:192..207): Int16 ¬ nil, -- sample range, if known
sampleMax(0:208..223): Int16 ¬ nil,
histogramLength(0:224..239): Card16 ¬ zero, -- number of words in histogram, nil if no histogram
pad(0:240..255): Card16 ¬ zero -- pad to multiple of 32 bits (not in file)
];
byteSizePhotometryPart: NAT ~ BYTES[PhotometryPart]-BYTES[Card16];
SignalType: TYPE ~ MACHINE DEPENDENT {
bw(0), -- black and white
red(1), -- red separation
blue(2), -- blue separation
green(3), -- green separation
cyan(4), -- cyan separation
magenta(5), -- magenta separation
yellow(6), -- yellow separation
x(7), -- x signal (CIE)
y(8), -- y signal
RGB(100), -- red, green, blue samples, 3 per pixel
CMY(101), -- cyan, magenta, yellow samples, 3 per pixel
CMYB(102), -- cyan, magenta, yellow, black samples, 4 per pixel
Yxy(103), -- Y, x, y (CIE) samples, 3 per pixel
comments(376B), -- specified in comments
undefined(377B) -- undefined
};
ScaleType: TYPE ~ MACHINE DEPENDENT {
nil(0), -- undefined
reflectance(1), -- reflectance or transmittance
density(2), -- optical density
comments(376B), -- specified in comments
undefined(377B) -- undefined
};
Value: TYPE ~ MACHINE DEPENDENT RECORD[
sample(0:0..15): Int16, -- 1000*(actual reflectance or density)
level(0:16..31): Card16 -- corresponding digital sample value
];
SpotType: TYPE ~ MACHINE DEPENDENT {
nil(0), -- undefined
rectangular(1), -- spotWidth by spotLength
circular(2), -- diameter=spotWidth, spotLength is undefined
comments(376B), -- specified in comments
undefined(377B) -- undefined
};
histogramScale: Int16 ~ [hi: 32767 / 256, lo: 32767 MOD 256];
CommentPart: TYPE ~ BCPLStringBody;
byteSizeCommentPart: NAT ~ BYTES[CommentPart]; -- maximum
BCPLStringBody: TYPE ~ PACKED ARRAY [0..256) OF CHAR;
If s is a POINTER TO BCPLStringBody, length is ORD[s[0]], text is s[1..length]
END.