DIRECTORY FS USING [StreamOpen], ImagerPixel USING [MakePixelMap], ImagerPixelArray USING [Join3, FromPixelMap, PixelArray], ImagerSample USING [Fill, NewSampleMap, Put, RasterSampleMap], IO USING [Close, GetChar, SetIndex, GetIndex, STREAM, EndOfStream], MacPICT, Rope USING [ROPE]; MacPICTImpl: CEDAR PROGRAM IMPORTS FS, ImagerPixel, ImagerPixelArray, ImagerSample, IO EXPORTS MacPICT ~ BEGIN PixelArray: TYPE ~ ImagerPixelArray.PixelArray; RasterSampleMap: TYPE ~ ImagerSample.RasterSampleMap; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; picHigh, picWide: INTEGER; rectTop, rectLeft, rectBottom, rectRight: CARDINAL; dstTop, dstLeft, dstBottom, dstRight: CARDINAL; rowBytes: CARDINAL; small: BOOL ¬ FALSE; smRed, smGreen, smBlue: RasterSampleMap ¬ NIL; clutRed, clutGreen, clutBlue: ARRAY [0..256) OF [0..256); GetByte: PROC [stream: STREAM] RETURNS [BYTE] ~ { RETURN [stream.GetChar[] - 0C] }; GetWord: PROC [stream: STREAM] RETURNS [CARDINAL] ~ { RETURN [(stream.GetChar[] - 0C) * 100H + (stream.GetChar[] - 0C)] }; SkipWord: PROC [stream: STREAM, count: CARDINAL] ~ { FOR i: CARDINAL IN [0..count) DO dummy: CARDINAL ¬ GetWord[stream]; ENDLOOP; }; ReadPixMap: PROC [stream: STREAM] ~ { rowBytes ¬ GetWord[stream]; rowBytes ¬ rowBytes - 8000H; IF rowBytes > 250 THEN small ¬ FALSE ELSE small ¬ TRUE; SkipWord[stream, 22]; -- ignore remaining part }; ReadColorTable: PROC [stream: STREAM] ~ { SkipWord[stream, 3]; -- ignore ctSeed and ctFlags FOR i: CARDINAL IN [0 .. GetWord[stream]] DO SkipWord[stream, 1]; clutRed[i] ¬ GetWord[stream] / 256; clutGreen[i] ¬ GetWord[stream] / 256; clutBlue[i] ¬ GetWord[stream] / 256; ENDLOOP; }; ReadDstRect: PROC [stream: STREAM] ~ { dstTop ¬ GetWord[stream]; dstLeft ¬ GetWord[stream]; dstBottom ¬ GetWord[stream]; dstRight ¬ GetWord[stream]; }; ReadPixData: PROC [stream: STREAM] ~ { colBytes, col: CARDINAL ¬ 0; scolBytes: BYTE ¬ 0; pos: LONG CARDINAL ¬ 0; FOR row: CARDINAL IN [dstTop .. dstBottom) DO IF small THEN scolBytes ¬ GetByte[stream] ELSE colBytes ¬ GetWord[stream]; -- dummy col ¬ dstLeft; WHILE col < rowBytes DO count: BYTE ~ GetByte[stream]; SELECT count FROM 80H => NULL; -- -128 ignored for backward compatibility > 80H => { -- -1..-127 => replicate next byte 2..128 times n: CARDINAL ¬ 101H - count; m: CARDINAL ¬ n; data: BYTE ~ GetByte[stream]; IF col + n > dstRight THEN n ¬ dstRight - col; ImagerSample.Fill[map: smRed, box: [[row, col], [row + 1, col + n]], value: clutRed[data]]; ImagerSample.Fill[map: smGreen, box: [[row, col], [row + 1, col + n]], value: clutGreen[data]]; ImagerSample.Fill[map: smBlue, box: [[row, col], [row + 1, col + n]], value: clutBlue[data]]; col ¬ col + m; }; ENDCASE => { -- 0..127 => copy 1..128 bytes uncompressed FOR i: CARDINAL IN [col .. col + count] DO data: BYTE ~ GetByte[stream]; IF i < dstRight THEN { ImagerSample.Put[map: smRed, index: [row, i], value: clutRed[data]]; ImagerSample.Put[map: smGreen, index: [row, i], value: clutGreen[data]]; ImagerSample.Put[map: smBlue, index: [row, i], value: clutBlue[data]]; }; ENDLOOP; col ¬ col + count + 1; }; ENDLOOP; IF col > rowBytes THEN ERROR; ENDLOOP; pos ¬ IO.GetIndex[stream]; IF pos MOD 2 ~= 0 THEN IO.SetIndex[stream, pos+1]; }; ToPixelArray: PUBLIC PROC [fileName: ROPE] RETURNS [pa: PixelArray] ~ { invalidVersion: PUBLIC ERROR = CODE; unsupportedOpCode: PUBLIC ERROR = CODE; opCode: CARDINAL; stream: STREAM ~ FS.StreamOpen[fileName]; IO.SetIndex[stream, 512]; -- skip header SkipWord[stream, 1]; -- ignore picSize rectTop ¬ GetWord[stream]; rectLeft ¬ GetWord[stream]; rectBottom ¬ GetWord[stream]; rectRight ¬ GetWord[stream]; picHigh ¬ rectBottom - rectTop; picWide ¬ rectRight - rectLeft; smRed ¬ ImagerSample.NewSampleMap[[max: [picHigh, picWide]], 8]; smGreen ¬ ImagerSample.NewSampleMap[[max: [picHigh, picWide]], 8]; smBlue ¬ ImagerSample.NewSampleMap[[max: [picHigh, picWide]], 8]; opCode ¬ GetWord[stream]; WHILE opCode ~= 00FFH DO SELECT opCode FROM 0000H => NULL; -- Nop 0001H => SkipWord[stream, 5]; -- ignore Clip operation 0011H => -- Version IF GetWord[stream] ~= 02FFH THEN ERROR invalidVersion; 001BH => SkipWord[stream, 3]; -- ignore RGBBkColor 001EH => NULL; -- do nothing for DefHilite 001FH => SkipWord[stream, 3]; -- ignore OpColor 0098H => { ReadPixMap[stream]; ReadColorTable[stream]; SkipWord[stream, 4]; -- ignore srcRect ReadDstRect[stream]; SkipWord[stream, 1]; -- ignore dstRect.Bottom,Right and mode ReadPixData[stream]; }; 0099H => { ReadPixMap[stream]; ReadColorTable[stream]; SkipWord[stream, 4]; -- ignore srcRect ReadDstRect[stream]; SkipWord[stream, 1]; -- ignore dstRect.Bottom,Right and mode SkipWord[stream, 5]; -- (GetWord[stream] - 10 + 4)]; ignore maskRgn ReadPixData[stream]; }; 00A0H => SkipWord[stream, 1]; -- ShortComment 0C00H => SkipWord[stream, 12]; -- ignore HeaderOp ENDCASE => ERROR unsupportedOpCode; opCode ¬ GetWord[stream ! IO.EndOfStream => EXIT;]; ENDLOOP; stream.Close[]; pa ¬ ImagerPixelArray.Join3[ImagerPixelArray.FromPixelMap[ pixelMap: ImagerPixel.MakePixelMap[smRed], box: [max: [picHigh, picWide]], scanMode: [down, right], immutable: FALSE], ImagerPixelArray.FromPixelMap[ pixelMap: ImagerPixel.MakePixelMap[smGreen], box: [max: [picHigh, picWide]], scanMode: [down, right], immutable: FALSE], ImagerPixelArray.FromPixelMap[ pixelMap: ImagerPixel.MakePixelMap[smBlue], box: [max: [picHigh, picWide]], scanMode: [down, right], immutable: FALSE]]; smRed ¬ NIL; smGreen ¬ NIL; smBlue ¬ NIL; }; END. * MacPICTImpl.mesa Copyright Σ 1988, 1992 by Xerox Corporation. All rights reserved. Fumihiko Shibata, March 14, 1989 11:57:15 am JST Import/Export of Macintosh PICT-format files. IO.Backup[stream, 0C]; Read the given Macintosh PICT-format file and return a PixelArray with its contents. Κ”•NewlineDelimiter –(cedarcode) style™code•Mark outsideHeaderšœ™Kšœ Οeœ7™BK™0K™K™-K™—šΟk ˜ Kšžœžœ˜Kšœ žœ˜!Kšœžœ#˜9Kšœ žœ,˜>Kšžœžœ&žœ˜CKšœ˜Kšœžœžœ˜—K˜KšΠbl œžœž˜Kšžœžœ/ž˜;Kšžœ˜šœž˜K˜Kšœ žœ˜/Kšœžœ ˜5Kšžœžœžœ˜Kšžœžœžœžœ˜K˜Kšœžœ˜Kšœ*žœ˜3Kšœ&žœ˜/Kšœ žœ˜Kšœžœžœ˜Kšœ*žœ˜.K˜KšœΟsœ  œ ˜9K˜š Οnœžœ žœžœžœ˜1Kšžœ˜K˜K˜—š ‘œžœ žœžœžœ˜5Kšžœ;˜AK˜—K˜š‘œžœ žœ  œ˜5šžœžœžœ ž˜ Kšœžœ˜"Kš œ˜—K˜—K˜š‘ œžœ žœ˜&K˜K˜Kš žœžœ žœžœ žœ˜7KšœΟc˜.Kšœ˜K˜—š‘œžœ žœ˜*K˜1šžœžœžœž˜,K˜K˜#K˜%K˜$Kš œ˜—K˜—š‘ œžœ žœ˜'K˜K˜K˜K˜K˜—K˜š‘ œžœ žœ˜'Kšœžœ˜Kšœ žœ˜Kšœž œ˜šžœžœžœž˜-Kšžœžœžœ’˜SK˜šžœž˜Kšœžœ˜šžœž˜Kšœžœ’*˜7šœ ’/˜;Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšžœžœ˜.K•StartOfExpansionν[map: ImagerSample.SampleMap, box: SF.Box _ [min: [s: -32768, f: -32768], max: [s: 32767, f: 32767]], value: ImagerSample.Sample _ 177777B (65535), function: ImagerSample.Function _ [dstFunc: null, srcFunc: null]]šœ\˜\K–ν[map: ImagerSample.SampleMap, box: SF.Box _ [min: [s: -32768, f: -32768], max: [s: 32767, f: 32767]], value: ImagerSample.Sample _ 177777B (65535), function: ImagerSample.Function _ [dstFunc: null, srcFunc: null]]šœ`˜`K–ν[map: ImagerSample.SampleMap, box: SF.Box _ [min: [s: -32768, f: -32768], max: [s: 32767, f: 32767]], value: ImagerSample.Sample _ 177777B (65535), function: ImagerSample.Function _ [dstFunc: null, srcFunc: null]]šœ^˜^K˜Kšœ˜—šžœ’+˜8šžœžœžœž˜*Kšœžœ˜šžœžœ˜K––[map: ImagerSample.SampleMap, index: SF.Vec, value: ImagerSample.Sample, function: ImagerSample.Function _ [dstFunc: null, srcFunc: null]]šœD˜DK––[map: ImagerSample.SampleMap, index: SF.Vec, value: ImagerSample.Sample, function: ImagerSample.Function _ [dstFunc: null, srcFunc: null]]šœH˜HK––[map: ImagerSample.SampleMap, index: SF.Vec, value: ImagerSample.Sample, function: ImagerSample.Function _ [dstFunc: null, srcFunc: null]]šœF˜FK˜—Kšžœ˜K˜Kšœ˜——Kšžœ˜—Kšžœžœžœ˜Kšžœ˜—Kšœžœ˜Kšžœžœžœžœ˜2Kšžœ™—Kšœ˜K˜—K˜š ‘ œžœžœ žœžœ˜GKšœT™TK–Κ[fileName: ROPE, accessOptions: FS.AccessOptions _ read, streamOptions: FS.StreamOptions _ (3)[TRUE, TRUE, TRUE], keep: CARDINAL _ 1B (1), createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ [vmPagesPerBuffer: 8, nBuffers: 2], extendFileProc: FS.ExtendFileProc, wantedCreatedTime: GMT _ nullGMT, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL, checkFileType: BOOL _ FALSE, fileType: FS.FileType _ [0B (0)]]˜Kšœžœžœžœ˜$Kšœžœžœžœ˜'Kšœžœ˜Kšœžœžœ˜)K–[self: STREAM, index: INT]šžœ’˜)Kšœ’˜&K˜K˜K˜K˜K˜K˜K˜K˜@K˜BK˜AK˜Kšœ œ œ ˜šž œž˜šžœž˜Kšœ žœ’˜KšœΠci˜6šœ ’ ˜Kšžœžœžœ˜6—Kšœ£˜2Kšœ žœ£˜+Kšœ£˜/˜ K˜K˜Kšœ’˜&Kšœ˜Kšœ’'˜