DIRECTORY Basics USING [bitsPerWord, bytesPerWord, LongMult, LongNumber], CountedVM USING [Allocate, Handle], FS USING [defaultStreamOptions, StreamOpen, StreamOptions], ImagerSample, IO USING [Close, GetIndex, SetIndex, STREAM, UnsafeGetBlock], PDFileFormat USING [ColorSamples, Command, Herald, LongCard, MaskRectangle, MaskRunGroup, MaskRunGroupRef, MaskSamples, MaskSamplesRef, MaskTrapezoid, passwordValue, Priority, Run, RunGroup, SampleArray, SetColorTile, StartImage, StoreLoad, Tile, versionValue], PDFileReader USING [ColorSamples, ColorSamplesRep, DeviceCommand, DeviceCommandRep, ErrorCode, Handle, MaskRectangle, MaskRectangleRep, MaskRunGroup, MaskRunGroupRep, MaskSamples, MaskSamplesRep, MaskTrapezoid, MaskTrapezoidRep, Rep, StateChange, StateChangeRep], Rope USING [ROPE], SafeStorage USING [ReclaimCollectibleObjects]; PDFileReaderImpl: CEDAR PROGRAM IMPORTS Basics, CountedVM, FS, IO, ImagerSample, SafeStorage EXPORTS PDFileReader ~ BEGIN OPEN PDFileReader; ROPE: TYPE ~ Rope.ROPE; bitsPerWord: NAT ~ Basics.bitsPerWord; Private: TYPE ~ REF PrivateRep; PrivateRep: TYPE ~ RECORD [ maskRectangle: MaskRectangle _ NIL, maskTrapezoid: MaskTrapezoid _ NIL, maskRunGroup: MaskRunGroup _ NIL, maskSamples: MaskSamples _ NIL, colorSamples: ColorSamples _ NIL, stateChange: StateChange _ NIL, loadStorage: CountedVM.Handle, runStorage: DeviceCommand _ NIL ]; ColorTileFromLoad: PUBLIC PROC [handle: Handle, colorTileLoadAddress: INT] RETURNS [colorTile: ImagerSample.RasterSampleMap, phase: CARDINAL] ~ TRUSTED { private: Private _ NARROW[handle.private]; wordsPerLine: NAT; words: INT; tile: LONG POINTER TO PDFileFormat.Tile; IF colorTileLoadAddress < 0 OR colorTileLoadAddress > handle.loadWords OR colorTileLoadAddress + SIZE[PDFileFormat.Tile] > handle.loadWords THEN RaisePDError[handle, badLoadReference, 0]; tile _ private.loadStorage.pointer + colorTileLoadAddress; wordsPerLine _ (tile.fSize+(bitsPerWord-1))/bitsPerWord; words _ Basics.LongMult[tile.sSize, wordsPerLine]; IF colorTileLoadAddress + SIZE[PDFileFormat.Tile] + words > handle.loadWords THEN RaisePDError[handle, badLoadReference, 0]; TRUSTED { colorTile _ ImagerSample.ObtainUnsafeDescriptor[size: [tile.sSize, tile.fSize], bitsPerSample: 1, bitsPerLine: wordsPerLine*bitsPerWord, base: [word: private.loadStorage.pointer + colorTileLoadAddress + SIZE[PDFileFormat.Tile], bit: 0], ref: handle, words: words, rawMin: [0, 0], delta: [tile.sMin, tile.fMin]]; }; phase _ tile.phase; }; RawStreamOptions: PROC RETURNS [options: FS.StreamOptions _ FS.defaultStreamOptions] ~ INLINE {options[tiogaRead] _ FALSE}; Open: PUBLIC PROC [fileName: ROPE] RETURNS [Handle] ~ { stream: IO.STREAM _ FS.StreamOpen[fileName: fileName, streamOptions: RawStreamOptions[]]; RETURN [FromStream[stream]]; }; FromStream: PUBLIC PROC [stream: IO.STREAM] RETURNS [handle: Handle] ~ { private: Private _ NEW[PrivateRep]; handle _ NEW[Rep]; handle.private _ private; handle.stream _ stream; handle.colorType _ none; handle.colorTileLoadAddress _ -1; handle.priority _ 0; handle.warningCount _ 0; ReadHerald[handle]; AllocateLoadSpace[handle]; }; ReadHerald: PROC [handle: Handle] ~ TRUSTED { herald: PDFileFormat.Herald; ReadBlock[handle, @herald, SIZE[PDFileFormat.Herald]]; IF herald.password # PDFileFormat.passwordValue THEN { RaisePDError[handle, invalidPassword, SIZE[PDFileFormat.Herald]]; }; IF herald.version # PDFileFormat.versionValue THEN { RaisePDWarning[handle, wrongFormatVersion, SIZE[PDFileFormat.Herald]]; }; IF NOT (herald.sResolution IN [10..10000]) OR NOT (herald.fResolution IN [10..10000]) THEN { RaisePDWarning[handle, unreasonableResolution, SIZE[PDFileFormat.Herald]]; }; IF NOT (herald.bandSSize IN [8..32767]) THEN { RaisePDWarning[handle, unreasonableBandSSize, SIZE[PDFileFormat.Herald]]; }; IF NOT (herald.imageSSize IN [80..32767]) OR NOT (herald.imageFSize IN [80..32767]) THEN { RaisePDWarning[handle, unreasonableImageSize, SIZE[PDFileFormat.Herald]]; }; IF LongCardOrd[herald.maxLoadWord] > 60000 THEN { RaisePDWarning[handle, unreasonableLoadSize, SIZE[PDFileFormat.Herald]]; }; IF NOT (herald.copies IN [1..200]) THEN { RaisePDWarning[handle, unreasonableNumberOfCopies, SIZE[PDFileFormat.Herald]]; }; handle.herald _ herald; handle.sSizeBand _ herald.bandSSize; }; LongCardOrd: PROC [longCard: PDFileFormat.LongCard] RETURNS [CARD] ~ { n: Basics.LongNumber ~ [pair[lo: longCard.lo, hi: longCard.hi]]; RETURN [n.lc] }; AllocateLoadSpace: PROC [handle: Handle] ~ { private: Private _ NARROW[handle.private]; maxLoadWord: CARD ~ LongCardOrd[handle.herald.maxLoadWord]; IF maxLoadWord > 0 THEN private.loadStorage _ CountedVM.Allocate[maxLoadWord]; }; Close: PUBLIC PROC [handle: Handle] ~ { IF handle.stream # NIL THEN {IO.Close[handle.stream]; handle.stream_NIL}; IF handle.private # NIL THEN { private: Private _ NARROW[handle.private]; private.loadStorage _ NIL; private.runStorage _ NIL; handle.private _ NIL; }; SafeStorage.ReclaimCollectibleObjects[]; }; ReadBlock: UNSAFE PROC [handle: Handle, dest: LONG POINTER, words: CARDINAL] ~ UNCHECKED { bytes: INT _ words*Basics.bytesPerWord; bytesRead: INT _ 0; bytesRead _ IO.UnsafeGetBlock[handle.stream, [dest, 0, bytes]]; IF bytesRead < bytes THEN RaisePDError[handle, unexpectedEOF, bytesRead/2]; }; CheckBB: PROC [handle: Handle, sMin, fMin, sSize, fSize: CARDINAL, errorWordCount: INT] ~ { IF LONG[sMin] + sSize > handle.herald.imageSSize OR LONG[fMin] + fSize > handle.herald.imageFSize OR fMin < handle.image.fMinPage OR fMin + fSize > handle.image.fMinPage + handle.image.fSizePage THEN RaisePDError[handle, objectOutOfBounds, errorWordCount]; IF sMin + sSize <= handle.sMinBand OR sMin >= handle.sMinBand+handle.sSizeBand THEN { RaisePDWarning[handle, objectOutOfBand, errorWordCount]; }; }; Get: PUBLIC PROC [handle: Handle, scanning: BOOLEAN _ FALSE] RETURNS [REF] ~ TRUSTED { private: Private _ NARROW[handle.private]; command: PDFileFormat.Command; BadLoadReference: PROC [dataWords: INT] ~ CHECKED { RaisePDError[handle, badLoadReference, SIZE[PDFileFormat.Command]+dataWords]; }; IF handle.priority = LAST[INT] THEN { ans: StateChange _ IF private.stateChange # NIL THEN private.stateChange ELSE (private.stateChange_NEW[StateChangeRep]); ans.loadChangeStart _ ans.loadChangeLength _ 0; handle.sMinBand _ handle.sMinBand + handle.sSizeBand; handle.bandNumber _ handle.bandNumber + 1; handle.priority _ 0; handle.colorType _ ink; ans.whatChanged _ bandChange; IF handle.bandNumber = handle.image.nBands THEN { ans.whatChanged _ imageEnd; handle.colorType _ none; }; RETURN [ans]; }; ReadBlock[handle, @command, SIZE[PDFileFormat.Command]]; WITH command SELECT FROM imagingCommand: PDFileFormat.Command.imaging => { IF handle.colorType = none THEN { RaisePDError[handle, missingStartImage, SIZE[PDFileFormat.Command]]; ERROR }; SELECT imagingCommand.com FROM maskSamplesRef => { ans: MaskSamples _ IF private.maskSamples # NIL THEN private.maskSamples ELSE (private.maskSamples_NEW[MaskSamplesRep]); maskSamplesRef: PDFileFormat.MaskSamplesRef; loadAddress: Basics.LongNumber; samples: LONG POINTER TO PDFileFormat.SampleArray; wordsPerLine: CARDINAL; words: INT; ReadBlock[handle, @maskSamplesRef, SIZE[PDFileFormat.MaskSamplesRef]]; IF ans.samples # NIL THEN ImagerSample.ReleaseDescriptor[ans.samples]; ans.samples _ NIL; loadAddress.hi _ imagingCommand.addrHighBits; loadAddress.lo _ maskSamplesRef.addrLowBits; ans.loadAddress _ loadAddress.li; IF ans.loadAddress < 0 OR ans.loadAddress + SIZE[PDFileFormat.SampleArray] > handle.loadWords THEN BadLoadReference[SIZE[PDFileFormat.MaskSamplesRef]]; samples _ private.loadStorage.pointer + loadAddress.li; wordsPerLine _ (samples.fSize+(bitsPerWord-1))/bitsPerWord; words _ Basics.LongMult[samples.sSize, wordsPerLine]; IF ans.loadAddress + SIZE[PDFileFormat.SampleArray] + words > handle.loadWords THEN BadLoadReference[SIZE[PDFileFormat.MaskSamplesRef]]; CheckBB[handle, maskSamplesRef.sMin, maskSamplesRef.fMin, samples.sSize, samples.fSize, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskSamplesRef]]; ans.samples _ ImagerSample.ObtainUnsafeDescriptor[size: [samples.sSize, samples.fSize], bitsPerSample: 1, bitsPerLine: wordsPerLine*bitsPerWord, base: [word: samples+SIZE[PDFileFormat.SampleArray], bit: 0], ref: handle, words: words, delta: [maskSamplesRef.sMin, maskSamplesRef.fMin]]; RETURN [ans]; }; maskRunGroupRef => { ans: MaskRunGroup _ IF private.maskRunGroup # NIL THEN private.maskRunGroup ELSE (private.maskRunGroup_NEW[MaskRunGroupRep]); maskRunGroupRef: PDFileFormat.MaskRunGroupRef; loadAddress: Basics.LongNumber; runGroup: LONG POINTER TO PDFileFormat.RunGroup; run: LONG POINTER TO PDFileFormat.Run; s: CARDINAL _ 0; runCount: CARDINAL _ 0; words: INT _ 0; fSize: CARDINAL _ 0; ReadBlock[handle, @maskRunGroupRef, SIZE[PDFileFormat.MaskRunGroupRef]]; loadAddress.hi _ imagingCommand.addrHighBits; loadAddress.lo _ maskRunGroupRef.addrLowBits; ans.ref _ private.loadStorage; ans.loadAddress _ loadAddress.li; IF ans.loadAddress < 0 OR ans.loadAddress + SIZE[PDFileFormat.RunGroup] > handle.loadWords THEN BadLoadReference[SIZE[PDFileFormat.MaskRunGroupRef]]; runGroup _ private.loadStorage.pointer + loadAddress.li; ans.pointer _ run _ private.loadStorage.pointer + loadAddress.li + SIZE[PDFileFormat.RunGroup]; WHILE s < runGroup.sSize DO IF INT[run-private.loadStorage.pointer] >= handle.loadWords THEN BadLoadReference[SIZE[PDFileFormat.MaskRunGroupRef]]; IF LONG[run.fMin] + run.fSize > fSize THEN fSize _ LONG[run.fMin] + run.fSize; IF run.lastRun THEN s _ s + 1; run _ run + SIZE[PDFileFormat.Run]; runCount _ runCount + 1; ENDLOOP; ans.runCount _ runCount; CheckBB[handle, maskRunGroupRef.sMin, maskRunGroupRef.fMin, runGroup.sSize, fSize, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskRunGroupRef]]; ans.sMin _ maskRunGroupRef.sMin; ans.fMin _ ans.fOffset _ maskRunGroupRef.fMin; ans.sSize _ runGroup.sSize; ans.fSize _ fSize; RETURN [ans]; }; maskRectangle => { ans: MaskRectangle _ IF private.maskRectangle # NIL THEN private.maskRectangle ELSE (private.maskRectangle_NEW[MaskRectangleRep]); maskRectangle: PDFileFormat.MaskRectangle; ReadBlock[handle, @maskRectangle, SIZE[PDFileFormat.MaskRectangle]]; CheckBB[handle, maskRectangle.sMin, maskRectangle.fMin, maskRectangle.sSize, maskRectangle.fSize, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskRectangle]]; ans.sMin _ maskRectangle.sMin; ans.fMin _ maskRectangle.fMin; ans.sSize _ maskRectangle.sSize; ans.fSize _ maskRectangle.fSize; RETURN [ans]; }; maskTrapezoid => { ans: MaskTrapezoid _ IF private.maskTrapezoid # NIL THEN private.maskTrapezoid ELSE (private.maskTrapezoid_NEW[MaskTrapezoidRep]); maskTrapezoid: PDFileFormat.MaskTrapezoid; fMin, fMax: INT; ReadBlock[handle, @maskTrapezoid, SIZE[PDFileFormat.MaskTrapezoid]]; fMin _ MIN[maskTrapezoid.fMin, maskTrapezoid.fMinLast]; fMax _ MAX[LONG[maskTrapezoid.fMin] + maskTrapezoid.fSize, LONG[maskTrapezoid.fMinLast] + maskTrapezoid.fSizeLast]; CheckBB[handle, maskTrapezoid.sMin, fMin, maskTrapezoid.sSize, fMax-fMin, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskTrapezoid]]; ans.sMin _ maskTrapezoid.sMin; ans.fMin _ maskTrapezoid.fMin; ans.fMinLast _ maskTrapezoid.fMinLast; ans.sSize _ maskTrapezoid.sSize; ans.fSize _ maskTrapezoid.fSize; ans.fSizeLast _ maskTrapezoid.fSizeLast; RETURN [ans]; }; maskRunGroup => { ans: MaskRunGroup _ IF private.maskRunGroup # NIL THEN private.maskRunGroup ELSE (private.maskRunGroup_NEW[MaskRunGroupRep]); maskRunGroup: PDFileFormat.MaskRunGroup; runGroup: PDFileFormat.RunGroup; run: PDFileFormat.Run; s: CARDINAL _ 0; runCount: INT _ 0; words: INT _ 0; fMin: CARDINAL _ LAST[CARDINAL]; fMax: CARDINAL _ FIRST[CARDINAL]; runGroupStart: INT; ReadBlock[handle, @maskRunGroup, SIZE[PDFileFormat.MaskRunGroup]]; ReadBlock[handle, @runGroup, SIZE[PDFileFormat.RunGroup]]; runGroupStart _ IO.GetIndex[handle.stream]; WHILE s < runGroup.sSize DO ReadBlock[handle, @run, SIZE[PDFileFormat.Run]]; IF run.fMin < fMin THEN fMin _ run.fMin; IF LONG[run.fMin] + run.fSize > fMax THEN fMax _ LONG[run.fMin] + run.fSize; IF run.lastRun THEN s _ s + 1; runCount _ runCount + 1; ENDLOOP; ans.runCount _ runCount; ans.loadAddress _ -1; IF runCount = 0 THEN { ans.pointer _ NIL; ans.ref _ NIL; RaisePDWarning[handle, emptyRunGroup, SIZE[PDFileFormat.MaskRunGroup]+SIZE[PDFileFormat.RunGroup]]; fMin _ fMax; } ELSE IF scanning THEN { ans.pointer _ NIL; ans.ref _ NIL; } ELSE { wordsNeeded: NAT _ runCount*SIZE[PDFileFormat.Run]; storage: DeviceCommand _ IF private.runStorage#NIL AND private.runStorage.wordCount>=wordsNeeded THEN private.runStorage ELSE (private.runStorage _ NEW[DeviceCommandRep[wordsNeeded]]); handle.stream.SetIndex[runGroupStart]; ans.ref _ storage; ans.pointer _ LOOPHOLE[@(storage[0])]; ReadBlock[handle, ans.pointer, wordsNeeded]; CheckBB[handle, maskRunGroup.sMin, fMin, runGroup.sSize, fMax-fMin, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskRunGroup]] }; ans.sMin _ maskRunGroup.sMin; ans.fMin _ fMin; ans.fOffset _ 0; ans.sSize _ runGroup.sSize; ans.fSize _ fMax; RETURN [ans]; }; maskSamples => { ans: MaskSamples _ IF private.maskSamples # NIL THEN private.maskSamples ELSE (private.maskSamples_NEW[MaskSamplesRep]); maskSamples: PDFileFormat.MaskSamples; samples: PDFileFormat.SampleArray; wordsPerLine: CARDINAL; words: LONG CARDINAL; ReadBlock[handle, @maskSamples, SIZE[PDFileFormat.MaskSamples]]; ReadBlock[handle, @samples, SIZE[PDFileFormat.SampleArray]]; CheckBB[handle, maskSamples.sMin, maskSamples.fMin, samples.sSize, samples.fSize, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskSamples]+SIZE[PDFileFormat.SampleArray]]; wordsPerLine _ (samples.fSize+(bitsPerWord-1))/bitsPerWord; words _ Basics.LongMult[samples.sSize, wordsPerLine]; ans.loadAddress _ -1; IF scanning THEN { handle.stream.SetIndex[handle.stream.GetIndex[]+words*Basics.bytesPerWord] } ELSE { ans.samples _ ImagerSample.NewSampleMap[box: [min: [maskSamples.sMin, maskSamples.fMin], max: [maskSamples.sMin+samples.sSize, maskSamples.fMin+samples.fSize]], bitsPerSample: 1, bitsPerLine: wordsPerLine*bitsPerWord]; ReadBlock[handle, ImagerSample.GetBase[ans.samples].word, words]; }; RETURN [ans]; }; colorSamples => { ans: ColorSamples _ IF private.colorSamples # NIL THEN private.colorSamples ELSE (private.colorSamples_NEW[ColorSamplesRep]); colorSamples: PDFileFormat.ColorSamples; samples: PDFileFormat.SampleArray; wordsPerLine: CARDINAL; words: LONG CARDINAL; ReadBlock[handle, @colorSamples, SIZE[PDFileFormat.ColorSamples]]; ReadBlock[handle, @samples, SIZE[PDFileFormat.SampleArray]]; CheckBB[handle, colorSamples.sMin, colorSamples.fMin, samples.sSize, samples.fSize, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.ColorSamples]+SIZE[PDFileFormat.SampleArray]]; wordsPerLine _ (samples.fSize+(bitsPerWord-1))/bitsPerWord; words _ Basics.LongMult[samples.sSize, wordsPerLine]; IF scanning THEN{ handle.stream.SetIndex[handle.stream.GetIndex[]+words*Basics.bytesPerWord] } ELSE { ans.samples _ ImagerSample.NewSampleMap[box: [min: [colorSamples.sMin, colorSamples.fMin], max: [colorSamples.sMin+samples.sSize, colorSamples.fMin+samples.fSize]], bitsPerSample: 1, bitsPerLine: wordsPerLine*bitsPerWord]; ReadBlock[handle, ImagerSample.GetBase[ans.samples].word, words]; }; RETURN [ans]; }; ENDCASE => { RaisePDError[handle, unrecognisedImagingCommand, SIZE[PDFileFormat.Command]]; ERROR}; }; controlCommand: PDFileFormat.Command.control => { ans: StateChange _ IF private.stateChange # NIL THEN private.stateChange ELSE (private.stateChange_NEW[StateChangeRep]); ans.loadChangeStart _ ans.loadChangeLength _ 0; IF handle.colorType = none THEN SELECT controlCommand.com FROM startImage, deviceCommand, storeLoad, endDocument => NULL; ENDCASE => { RaisePDError[handle, missingStartImage, SIZE[PDFileFormat.Command]]; ERROR }; SELECT controlCommand.com FROM startImage => { startImage: PDFileFormat.StartImage; ReadBlock[handle, @startImage, SIZE[PDFileFormat.StartImage]]; IF startImage.filler # 0 THEN { RaisePDWarning[handle, nonZeroFill, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.StartImage]]; }; IF (LONG[startImage.passBands]+startImage.nBands)*handle.sSizeBand >= handle.herald.imageSSize+handle.sSizeBand OR LONG[startImage.fMinPage]+startImage.fSizePage > handle.herald.imageFSize THEN { RaisePDWarning[handle, imageBoundsExceedPageBounds, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.StartImage]]; }; IF handle.colorType # none AND handle.bandNumber < handle.image.nBands THEN RaisePDWarning[handle, tooFewBands, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.StartImage]]; handle.image _ startImage; ans.whatChanged _ imageStart; handle.priority _ 0; handle.colorType _ ink; handle.bandNumber _ 0; handle.sMinBand _ startImage.passBands*handle.sSizeBand; RETURN [ans] }; setPriority => { priorityLow: PDFileFormat.Priority; priority: Basics.LongNumber; ReadBlock[handle, @priorityLow, SIZE[PDFileFormat.Priority]]; priority.hi _ controlCommand.rest; priority.lo _ priorityLow; handle.priority _ priority.li; ans.whatChanged _ priorityChange; RETURN [ans] }; setColorInk => { handle.colorType _ ink; ans.whatChanged _ colorChange; RETURN [ans] }; setColorClear => { handle.colorType _ clear; ans.whatChanged _ colorChange; RETURN [ans] }; setColorTile => { tile: LONG POINTER TO PDFileFormat.Tile; words: INT; setColorTile: PDFileFormat.SetColorTile; ReadBlock[handle, @setColorTile, SIZE[PDFileFormat.SetColorTile]]; handle.colorTileLoadAddress _ LongCardOrd[setColorTile.addr]; IF handle.colorTileLoadAddress < 0 OR handle.colorTileLoadAddress > handle.loadWords OR handle.colorTileLoadAddress + SIZE[PDFileFormat.Tile] > handle.loadWords THEN BadLoadReference[SIZE[PDFileFormat.SetColorTile]]; tile _ private.loadStorage.pointer + LongCardOrd[setColorTile.addr]; words _ Basics.LongMult[tile.sSize, (tile.fSize+(bitsPerWord-1))/bitsPerWord]; IF INT[LongCardOrd[setColorTile.addr]] + SIZE[PDFileFormat.Tile] + words > handle.loadWords THEN BadLoadReference[SIZE[PDFileFormat.SetColorTile]]; SELECT controlCommand.rest FROM 0 => handle.colorType _ opaqueTile; 1 => handle.colorType _ transparentTile; ENDCASE => { handle.colorType _ opaqueTile; RaisePDWarning[handle, unknownColorTileFlag, SIZE[PDFileFormat.Command]]; }; ans.whatChanged _ colorChange; RETURN [ans]; }; endBand => { handle.priority _ LAST[INT]; ans.whatChanged _ priorityChange; RETURN [ans] }; endDocument => { ans.whatChanged _ documentEnd; RETURN [ans]; }; storeLoad => { storeLoad: PDFileFormat.StoreLoad; firstAddress: CARD; ReadBlock[handle, @storeLoad, SIZE[PDFileFormat.StoreLoad]]; firstAddress _ LongCardOrd[storeLoad.firstAddress]; IF storeLoad.firstAddress.hi > 255 OR firstAddress + storeLoad.wordCount > LongCardOrd[handle.herald.maxLoadWord] THEN {RaisePDError[handle, loadOutOfBounds, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.StoreLoad]]; ERROR}; ReadBlock[handle, private.loadStorage.pointer+firstAddress, storeLoad.wordCount]; ans.whatChanged _ loadChange; ans.loadChangeStart _ firstAddress; ans.loadChangeLength _ storeLoad.wordCount; handle.loadWords _ MAX[handle.loadWords, ans.loadChangeStart + ans.loadChangeLength]; RETURN [ans]; }; deviceCommand => { deviceCommand: DeviceCommand; wordCount: CARDINAL; ReadBlock[handle, @wordCount, SIZE[CARDINAL]]; deviceCommand _ NEW[DeviceCommandRep[wordCount]]; IF wordCount > 0 THEN { ReadBlock[handle, @(deviceCommand[0]), wordCount]; }; RETURN [deviceCommand]; }; ENDCASE => {RaisePDError[handle, unrecognisedControlCommand, SIZE[PDFileFormat.Command]]; ERROR}; }; ENDCASE => {RaisePDError[handle, unrecognisedCommandType, SIZE[PDFileFormat.Command]]; ERROR}; }; Keep: PUBLIC PROC [handle: Handle, ref: REF] RETURNS [REF] ~ { private: Private _ NARROW[handle.private]; SELECT ref FROM private.maskRectangle => private.maskRectangle _ NIL; private.maskTrapezoid => private.maskTrapezoid _ NIL; private.maskRunGroup => private.maskRunGroup _ NIL; private.maskSamples => private.maskSamples _ NIL; private.colorSamples => private.colorSamples _ NIL; private.stateChange => private.stateChange _ NIL; ENDCASE => NULL; RETURN [ref] }; Error: PUBLIC ERROR [handle: Handle, code: ErrorCode, wordIndex, wordCount: INT, description: ROPE] ~ CODE; Warning: PUBLIC SIGNAL [handle: Handle, code: ErrorCode, wordIndex, wordCount: INT, description: ROPE] ~ CODE; RaisePDError: PROC [handle: Handle, code: ErrorCode, words: INT] ~ { index: INT _ IO.GetIndex[handle.stream]; wordIndex: INT _ index/Basics.bytesPerWord - words; IO.SetIndex[handle.stream, wordIndex*Basics.bytesPerWord]; ERROR Error[handle, code, wordIndex, words, descriptionFor[code]]; }; RaisePDWarning: PROC [handle: Handle, code: ErrorCode, words: INT] ~ { index: INT _ IO.GetIndex[handle.stream]; wordIndex: INT _ index/Basics.bytesPerWord - words; IO.SetIndex[handle.stream, wordIndex*Basics.bytesPerWord]; handle.warningCount _ handle.warningCount + 1; SIGNAL Warning[handle, code, wordIndex, words, descriptionFor[code]]; IO.SetIndex[handle.stream, index]; }; descriptionFor: ARRAY ErrorCode OF ROPE ~ [ invalidPassword: "Invalid PD file password", objectOutOfBounds: "Object exceeds page boundaries", missingStartImage: "This command must be in the scope of a StartImage command", badLoadReference: "Reference to load exceeds load bounds", unrecognisedImagingCommand: "Unrecognised imaging command", loadOutOfBounds: "Attempt to exceed load size declared in herald", unrecognisedControlCommand: "Unrecognised control command", unrecognisedCommandType: "Unrecognised command type", unexpectedEOF: "Unexpected end of file", wrongFormatVersion: "The version of the PD file format does not match the software version", unreasonableResolution: "The resolution is not in a reasonable range", unreasonableBandSSize: "The band size is not in a reasonable range", unreasonableImageSize: "The image size is not in a reasonable range", unreasonableLoadSize: "The load size is not in a reasonable range", unreasonableNumberOfCopies: "The requested number of copies is not in a reasonable range", objectOutOfBand: "Object does not touch band in which it is used", emptyRunGroup: "Run group has zero runs", nonZeroFill: "Fill bits in startImage command are non-zero", imageBoundsExceedPageBounds: "Image bounds in startImage command exceed page boundaries", tooFewBands: "Too few bands in image", unknownColorTileFlag: "Unknown flag byte in setColorTile command" ]; END. κPDFileReaderImpl.mesa Copyright c 1983, 1984, 1985 by Xerox Corporation. All rights reserved. Ken Pier, September 17, 1985 2:06:20 pm PDT Michael Plass, February 6, 1987 7:52:48 pm PST Doug Wyatt, March 7, 1985 6:29:25 pm PST Κ-˜code™Kšœ Οmœ=™HK™+K™.K™(K™—šΟk ˜ Kšœžœ3˜?Kšœ žœ˜#Kšžœžœ3˜;Kšœ ˜ Kšžœžœžœ˜=Kšœ žœσ˜…Kšœ žœυ˜‡Kšœžœžœ˜Kšœ žœ˜.K˜—KšΠblœž ˜Kšžœžœžœ˜˜@Kšžœ9˜=Kšžœ ˜"šžœ*žœ˜2Kšœ8˜8Kšœ˜—Kšœ˜K˜—š œžœžœžœžœžœžœžœ˜VKšœžœ˜*Kšœ˜š œžœ žœžœ˜3Kšœ'žœ"˜MKšœ˜—šžœžœžœžœ˜%Kš œžœžœžœžœžœ˜xKšœ/˜/Kšœ5˜5Kšœ*˜*Kšœ˜Kšœ˜Kšœ˜šžœ)žœ˜1Kšœ˜Kšœ˜Kšœ˜—Kšžœ˜ Kšœ˜—Kšœžœ˜8šžœ žœž˜š œ#˜1šžœžœ˜!Kšœ(žœ˜DKšž˜Kšœ˜—šžœž˜š œ˜Kš œžœžœžœžœžœ˜xKšœ,˜,K˜Kšœ žœžœžœ˜2Kšœžœ˜Kšœžœ˜ Kšœ#žœ˜FKšžœžœžœ-˜FKšœžœ˜Kšœ-˜-Kšœ,˜,Kšœ!˜!Kš žœžœžœ.žœžœ˜—Kšœ7˜7Kšœ;˜;Kšœ5˜5Kšžœžœ6žœžœ˜ˆKšœXžœžœ˜–K–Υ[size: SF.Vec, bitsPerSample: ImagerSample.BitsPerSample, bitsPerLine: INT, base: PrincOps.BitAddress, ref: REF ANY, words: INT, rawMin: SF.Vec _ [s: 0, f: 0], delta: SF.Vec _ [s: 0, f: 0]]šœ¦žœs˜Kšžœ˜ Kšœ˜—š œ˜Kš œžœžœžœžœžœ˜}Kšœ.˜.K˜Kšœ žœžœžœ˜0Kšœžœžœžœ˜&Kšœžœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜Kšœ$žœ ˜HKšœ-˜-Kšœ-˜-Kšœ˜Kšœ!˜!Kš žœžœžœ+žœžœ ˜•Kšœ8˜8KšœCžœ˜_šžœž˜Kšžœžœ6žœžœ ˜vKšžœžœžœ žœ˜NKšžœ žœ ˜Kšœ žœ˜#Kšœ˜Kšžœ˜—Kšœ˜KšœSžœžœ ˜’Kšœ ˜ Kšœ.˜.Kšœ˜Kšœ˜Kšžœ˜ Kšœ˜—š  œ˜Kš œžœžœžœžœžœ˜‚Kšœ*˜*Kšœ"žœ˜DKšœbžœžœ˜ŸKšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšžœ˜ Kšœ˜—š  œ˜Kš œžœžœžœžœžœ˜‚Kšœ*˜*Kšœ žœ˜Kšœ"žœ˜DKšœžœ-˜7Kšœžœžœ,žœ4˜sKšœJžœžœ˜‡Kšœ˜Kšœ˜Kšœ&˜&Kšœ ˜ Kšœ ˜ Kšœ(˜(Kšžœ˜ Kšœ˜—š  œ˜Kš œžœžœžœžœžœ˜}Kšœ(˜(Kšœ ˜ Kšœ˜Kšœžœ˜Kšœ žœ˜Kšœžœ˜Kšœžœžœžœ˜ Kšœžœžœžœ˜!Kšœžœ˜Kšœ!žœ˜BKšœžœ˜:Kšœžœ˜+šžœž˜Kšœžœ˜0Kšžœžœ˜(Kšžœžœžœžœ˜LKšžœ žœ ˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜šžœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ&žœžœ˜cKšœ ˜ Kšœ˜—šžœžœ žœ˜Kšœžœ˜Kšœ žœ˜Kšœ˜—šžœ˜Kšœ žœ žœ˜3Kš œžœžœžœ+žœžœžœ!˜ΉKšœ&˜&Kšœ˜Kšœžœ˜&Kšœ,˜,KšœDžœžœ˜Kšœ˜—Kšœ˜Kšœ˜K˜Kšœ˜Kšœ˜Kšžœ˜ Kšœ˜—š  œ˜Kš œžœžœžœžœžœ˜xKšœ&˜&Kšœ"˜"Kšœžœ˜Kšœžœžœ˜Kšœ žœ˜@Kšœžœ˜Kšœ5žœ˜:šžœ˜ Kšœ(žœ˜DKšž˜Kšœ˜——šžœž˜š  œ˜Kšœ$˜$Kšœžœ˜>šžœžœ˜Kšœ$žœžœ˜^Kšœ˜—Kšžœžœg˜ošžœžœFžœ˜SKšœ4žœžœ˜nKšœ˜—šžœžœ)ž˜KKšœ$žœžœ˜^—Kšœ˜Kšœ˜Kšœ˜K˜Kšœ˜Kšœ8˜8Kšžœ˜ Kšœ˜—š  œ˜Kšœ#˜#Kšœ˜Kšœ žœ˜=Kšœ"˜"Kšœ˜Kšœ˜Kšœ!˜!Kšžœ˜ Kšœ˜—š  œ˜K˜Kšœ˜Kšžœ˜ Kšœ˜—š  œ˜K˜Kšœ˜Kšžœ˜ Kšœ˜—š  œ˜Kšœžœžœžœ˜(Kšœžœ˜ Kšœ(˜(Kšœ!žœ˜BKšœ=˜=Kš žœ!žœ0žœžœ'žœžœ˜ΨKšœD˜DKšœN˜NKš žœžœ#žœ/žœžœ˜“šžœž˜K˜#Kšœ(˜(šžœ˜ K˜Kšœ-žœ˜IKšœ˜——Kšœ˜Kšžœ˜ Kšœ˜—š œ˜ Kšœžœžœ˜Kšœ!˜!Kšžœ˜ Kšœ˜—š  œ˜Kšœ˜Kšžœ˜ Kšœ˜—š  œ˜Kšœ"˜"Kšœžœ˜Kšœžœ˜Kšœžœ˜*šžœž˜Kšœ1žœ˜5Kšœ1žœ˜5Kšœ/žœ˜3Kšœ-žœ˜1Kšœ/žœ˜3Kšœ-žœ˜1Kšžœžœ˜—Kšžœ˜ Kšœ˜K˜—š  œžœžœ9žœžœžœ˜kK˜—š  œžœžœ9žœžœžœ˜nK˜—š  œžœ*žœ˜DKšœžœžœ˜(Kšœ žœ%˜3Kšžœ8˜:Kšžœ=˜BKšœ˜K˜—š œžœ*žœ˜FKšœžœžœ˜(Kšœ žœ%˜3Kšžœ8˜:Kšœ.˜.Kšžœ?˜EKšžœ ˜"Kšœ˜K˜—šœžœ žœžœ˜+Kšœ,˜,Kšœ4˜4KšœO˜OKšœ:˜:Kšœ;˜;KšœB˜BKšœ;˜;Kšœ5˜5Kšœ(˜(Kšœ\˜\KšœF˜FKšœD˜DKšœE˜EKšœC˜CKšœZ˜ZKšœB˜BKšœ)˜)Kšœ<˜