<<>> <> <> <> <> 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 <> ]; 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; <> <<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; <> END.