PROC [ fileName: Rope.
s:
IO.
STREAM ←
NIL;
BEGIN ENABLE UNWIND => GOTO Punt;
moDayYr, name: Rope.ROPE;
ReadMDYName:
PROC =
BEGIN
nameWords: CARDINAL;
nameText: REF TEXT;
mdyText: REF TEXT ← NEW[TEXT[6]];
IF s.GetBlock[mdyText] # 6 THEN ERROR;
moDayYr ← Rope.FromRefText[mdyText];
nameWords ← ReadMebesWord[s];
nameText ← NEW[TEXT[2*nameWords]];
IF s.GetBlock[nameText] # 2*nameWords THEN ERROR;
IF nameText[nameText.length-1] = '\000 THEN nameText.length ← nameText.length-1;
name ← Rope.FromRefText[nameText];
END;
nHeaderFields, startDrawing, extraFields: Byte;
pixelSize: Meters;
size: CDMEBES.MEBESPosition; -- pixels
field2WordCnt: CARDINAL ← 0;
stripeHeight: INT ← 255;
stripe, segment: INT ← 0;
maxStripes: CARDINAL ← 0;
s ← FS.StreamOpen[fileName];
nHeaderFields ← ReadMebesByte[s];
startDrawing ← ReadMebesByte[s];
SELECT startDrawing
FROM
3, 6 => {
-- Mode 1/2
pixelSize ← 1500.0E-9/startDrawing -- meters -- ;
size.x ← ReadMebesWord[s];
size.y ← ReadMebesWord[s];
ReadMDYName[];
extraFields ← nHeaderFields-1;
};
5 => {
-- extended or reticle mode
patFileBlockCount: CARDINAL;
pixelSize ← (REAL[ReadMebesDoubleWord[s] -- (10^-6)*(2^-28) meters -- ])*1.0E-6/(16384.0*16384.0);
stripeHeight ← ReadMebesWord[s];
size.x ← ReadMebesDoubleWord[s];
size.y ← ReadMebesDoubleWord[s];
ReadMDYName[];
field2WordCnt ← ReadMebesWord[s];
IF field2WordCnt > 0
THEN {
patFileBlockCount ← ReadMebesWord[s];
IF s.GetLength[] # patFileBlockCount*blockSize THEN ERROR NotMEBESFormat;
field2WordCnt ← field2WordCnt-1;
}
ELSE ERROR NotMEBESFormat;
extraFields ← nHeaderFields-2;
};
ENDCASE => ERROR NotMEBESFormat;
did ← NEW[DropInDescriptorRec[MAX[field2WordCnt/2, 1]]];
did.fileName ← fileName;
did.created ← FS.GetInfo[FS.OpenFileFromStream[s]].created;
did.lastChecked ← BasicTime.Now[];
did.pixelSize ← pixelSize;
did.sizeX ← pixelSize*size.x;
did.sizeY ← pixelSize*size.y;
did.clip ← [x1: 0, y1: 0, x2: size.x, y2: size.y];
did.stripeHeight ← stripeHeight;
maxStripes ← (size.y+stripeHeight-1)/stripeHeight;
IF field2WordCnt > 0
THEN {
-- reticle mode
IF (field2WordCnt MOD 2) # 0 THEN ERROR NotMEBESFormat;
FOR i:
NAT
IN [0..field2WordCnt/2)
DO
did[i] ← NEW[StripeDirectory[maxStripes]];
did[i].nStripes ← 0;
did[i][0].firstBlock ← ReadMebesWord[s];
did[i][0].firstWordWithinBlock ← ReadMebesWord[s];
ENDLOOP;
}
ELSE {
-- mode 1/2 or extended
did[0] ← NEW[StripeDirectory[maxStripes]];
did[0].nStripes ← 0;
};
FOR i:
INT
IN [0..extraFields)
DO
-- read across extraneous fields
wc: CARDINAL = ReadMebesWord[s];
FOR j:
CARDINAL
IN [0..wc)
DO
[] ← ReadMebesWord[s];
ENDLOOP;
ENDLOOP;
segment ← stripe ← 0;
DO
NoteStripePos:
PROC [] = {
WHILE did[segment].nStripes < stripe
DO
-- fill in empty space with defaults
did[segment].nStripes ← did[segment].nStripes+1;
did[segment][did[segment].nStripes] ← [];
ENDLOOP;
did[segment][stripe] ← [
firstBlock: (index/blockSize)+1,
firstWordWithinBlock: ((index MOD blockSize)/2)+1
];
};
t1: CARDINAL ← ReadMebesWord[s];
index: INT;
SELECT t1
MOD 100B
FROM
16 => s.SetIndex[s.GetIndex[]+6]; -- Manhattan Rectangle
17, 18, 19 => s.SetIndex[s.GetIndex[]+10]; -- Parallelogram, Trapezoid 1/2
20 => s.SetIndex[s.GetIndex[]+12]; -- Trapezoid 3
10 => {
-- start of segment
segment ← (t1/256)-1;
IF NOT segment IN [0..did.nSegments) THEN ERROR;
index ← s.GetIndex[]-2; -- to account for word containing t1
stripe ← 0;
NoteStripePos[];
};
2, 7 =>
BEGIN -- start of stripe
index ← s.GetIndex[]-2; -- to account for word containing t1
stripe ← (IF (t1 MOD 100) = 7 THEN t1/256 ELSE ReadMebesWord[s])-1;
NoteStripePos[];
END;
8 => NULL; -- end of stripe
4 => RETURN; -- end of drawing
9 => {
-- end of buffer
i: INT = s.GetIndex[]+blockSize-1;
s.SetIndex[i - (i MOD blockSize)];
};
ENDCASE => ERROR NotMEBESFormat;
ENDLOOP;
EXITS Punt => NULL;
END; -- of ENABLE block