DIRECTORY Basics, CountedVM, FS, IO, PDFileFormat, Rope, ImagerPixelMaps, PDFileReader, SafeStorage; PDFileReaderImpl: CEDAR PROGRAM IMPORTS Basics, CountedVM, FS, IO, ImagerPixelMaps, SafeStorage EXPORTS PDFileReader ~ BEGIN OPEN PDFileReader; bitsPerWord: NAT ~ Basics.bitsPerWord; RawStreamOptions: PROC RETURNS [options: FS.StreamOptions _ FS.defaultStreamOptions] ~ INLINE {options[tiogaRead] _ FALSE}; 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, tempRefRep: REF ImagerPixelMaps.PixelMapRep -- temp for building tiles ]; ColorTileFromLoad: PUBLIC PROC [handle: Handle, colorTileLoadAddress: INT, scratch: REF ImagerPixelMaps.PixelMapRep] RETURNS [colorTile: ImagerPixelMaps.Tile] ~ TRUSTED { private: Private _ NARROW[handle.private]; pixelMap: ImagerPixelMaps.PixelMap _ [0,0,0,0,0,0,private.tempRefRep]; 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; words _ Basics.LongMult[tile.sSize, (tile.fSize+(bitsPerWord-1))/bitsPerWord]; IF colorTileLoadAddress + SIZE[PDFileFormat.Tile] + words > handle.loadWords THEN RaisePDError[handle, badLoadReference, 0]; pixelMap.sOrigin _ tile.sMin; pixelMap.fOrigin _ tile.fMin; pixelMap.sSize _ tile.sSize; pixelMap.fSize _ tile.fSize; pixelMap.refRep.pointer _ private.loadStorage.Pointer + colorTileLoadAddress + SIZE[PDFileFormat.Tile]; pixelMap.refRep.words _ words; pixelMap.refRep.rast _ (tile.fSize+(bitsPerWord-1))/bitsPerWord; pixelMap.refRep.lines _ tile.sSize; colorTile _ ImagerPixelMaps.CreateTile[pixelMap, tile.phase, 100, scratch]; }; 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]; private.tempRefRep _ NEW[ImagerPixelMaps.PixelMapRep _ [ ref: private.loadStorage, pointer: NIL, words: 0, lgBitsPerPixel: 0, rast: 0, lines: 0 ]]; }; 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 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; }; AllocateLoadSpace: PROC [handle: Handle] ~ { private: Private _ NARROW[handle.private]; IF handle.herald.maxLoadWord > 0 THEN private.loadStorage _ CountedVM.Allocate[handle.herald.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.tempRefRep.ref _ NIL; private.tempRefRep _ NIL; private.loadStorage _ 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; words: INT; refRep: REF ImagerPixelMaps.PixelMapRep _ IF ans.samples.refRep = NIL THEN NEW[ImagerPixelMaps.PixelMapRep _ [ ref: private.loadStorage, pointer: NIL, words: 0, rast: 0, lines: 0, lgBitsPerPixel: 0 ]] ELSE ans.samples.refRep; ReadBlock[handle, @maskSamplesRef, SIZE[PDFileFormat.MaskSamplesRef]]; loadAddress.highbits _ imagingCommand.addrHighBits; loadAddress.lowbits _ 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; words _ Basics.LongMult[samples.sSize, (samples.fSize+(bitsPerWord-1))/bitsPerWord]; 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]]; refRep.pointer _ samples+SIZE[PDFileFormat.SampleArray]; refRep.words _ words; refRep.rast _ (samples.fSize+(bitsPerWord-1))/bitsPerWord; refRep.lines _ samples.sSize; ans.samples _ [sOrigin: maskSamplesRef.sMin, fOrigin: maskSamplesRef.fMin, sMin: 0, fMin: 0, sSize: samples.sSize, fSize: samples.fSize, refRep: refRep]; 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.highbits _ imagingCommand.addrHighBits; loadAddress.lowbits _ 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 { storage: DeviceCommand _ NEW[DeviceCommandRep[runCount*SIZE[PDFileFormat.Run]]]; handle.stream.SetIndex[runGroupStart]; ans.ref _ storage; ans.pointer _ LOOPHOLE[@(storage[0])]; ReadBlock[handle, ans.pointer, storage.wordCount]; CheckBB[handle, maskRunGroup.sMin, fMin, runGroup.sSize, fMax-fMin, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.MaskRunGroupRef]] }; 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; 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]]; words _ Basics.LongMult[samples.sSize, (samples.fSize+(bitsPerWord-1))/bitsPerWord]; ans.loadAddress _ -1; IF scanning THEN { handle.stream.SetIndex[handle.stream.GetIndex[]+words*Basics.bytesPerWord] } ELSE { ans.samples _ ImagerPixelMaps.Create[0, [maskSamples.sMin, maskSamples.fMin, samples.sSize, samples.fSize]]; IF ans.samples.refRep.words # words THEN ERROR; ReadBlock[handle, ans.samples.refRep.pointer, words]; }; RETURN [ans]; }; colorSamples => { ans: ColorSamples _ IF private.colorSamples # NIL THEN private.colorSamples ELSE (private.colorSamples_NEW[ColorSamplesRep]); colorSamples: PDFileFormat.ColorSamples; samples: PDFileFormat.SampleArray; 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]]; words _ Basics.LongMult[samples.sSize, (samples.fSize+(bitsPerWord-1))/bitsPerWord]; IF scanning THEN{ handle.stream.SetIndex[handle.stream.GetIndex[]+words*Basics.bytesPerWord] } ELSE { ans.samples _ ImagerPixelMaps.Create[0, [colorSamples.sMin, colorSamples.fMin, samples.sSize, samples.fSize]]; IF ans.samples.refRep.words # words THEN ERROR; ReadBlock[handle, ans.samples.refRep.pointer, 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.highbits _ controlCommand.rest; priority.lowbits _ 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 _ 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 + setColorTile.addr; words _ Basics.LongMult[tile.sSize, (tile.fSize+(bitsPerWord-1))/bitsPerWord]; IF INT[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; ReadBlock[handle, @storeLoad, SIZE[PDFileFormat.StoreLoad]]; IF storeLoad.firstAddress > LAST[LONG CARDINAL]/256 OR storeLoad.firstAddress + storeLoad.wordCount > handle.herald.maxLoadWord THEN {RaisePDError[handle, loadOutOfBounds, SIZE[PDFileFormat.Command]+SIZE[PDFileFormat.StoreLoad]]; ERROR}; ReadBlock[handle, private.loadStorage.Pointer+storeLoad.firstAddress, storeLoad.wordCount]; ans.whatChanged _ loadChange; ans.loadChangeStart _ storeLoad.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. xPDFileReaderImpl.mesa Michael Plass, April 6, 1984 1:03:55 pm PST Last Edited by: Pier, December 13, 1983 3:47 pm Κ˜J™J™+J™/unitšΟk ˜ JšœZ˜Z—šΟnœ ˜Jšœ8˜?Jšœ ˜Jšœœœ˜—˜Jšœ œ˜&Jšžœœœ œœœœ˜{J˜—Jšœ œœ ˜šœ œœ˜Jšœœ˜#Jšœœ˜#Jšœœ˜!Jšœœ˜Jšœœ˜!Jšœœ˜Jšœœ˜Jšœ œΟc˜FJšœ˜J˜—šžœœœ(œ œœ%œ˜ͺJšœœ˜*JšœF˜FJšœœ˜ Jšœœœœ˜(Jš œœ)œœ'œ+˜»Jšœ:˜:JšœN˜NJšœœ/œ+˜|Jšœ˜Jšœ˜Jšœ˜Jšœ˜JšœOœ˜gJšœ˜Jšœ@˜@Jšœ#˜#JšœK˜KJšœ˜J˜—š žœœœ œœ ˜7JšœœœœC˜YJšœ˜Jšœ˜J˜—š ž œœœ œœœ˜HJšœœ ˜#Jšœ œ˜Jšœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšœ˜Jšœ˜šœœ ˜8Jšœ˜Jšœ œ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜J˜—šž œœœ˜-Jšœ˜Jšœœ˜6šœ.œ˜6Jšœ&œ˜AJšœ˜—šœ,œ˜4Jšœ+œ˜FJšœ˜—Jšœœœ ˜*šœœœœ˜1Jšœ/œ˜JJšœ˜—šœœœ œ˜.Jšœ.œ˜IJšœ˜—Jšœœœ ˜)šœœœœ˜0Jšœ.œ˜IJšœ˜—šœœ˜$Jšœ-œ˜HJšœ˜—šœœœ œ˜)Jšœ3œ˜NJšœ˜—Jšœ˜Jšœ$˜$Jšœ˜J˜—šžœœ˜,Jšœœ˜*JšœœE˜jJšœ˜J˜—šžœœœ˜'Jš œœœœ%œ˜Išœœœ˜Jšœœ˜*Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœ˜—J˜(Jšœ˜J˜—šž œœœœœ œ œ˜ZJšœœ˜'Jšœ œ˜Jšœ œ1˜?Jšœœ2˜KJšœ˜J˜—šžœœ,œœ˜[Jšœœ)˜0Jšœœ)˜0Jšœ˜Jšœ>˜@Jšœ9˜=Jšœ ˜"šœ*œ˜2Jšœ8˜8Jšœ˜—Jšœ˜J˜—šžœœœœœœœœ˜VJšœœ˜*Jšœ˜šžœœ œœ˜3Jšœ'œ"˜MJšœ˜—šœœœœ˜%Jš œœœœœœ˜xJšœ/˜/Jšœ5˜5Jšœ*˜*Jšœ˜Jšœ˜Jšœ˜šœ)œ˜1Jšœ˜Jšœ˜Jšœ˜—Jšœ˜ Jšœ˜—Jšœœ˜8šœ œ˜šžœ#˜1šœœ˜!Jšœ(œ˜DJš˜Jšœ˜—šœ˜šžœ˜Jš œœœœœœ˜xJšœ,˜,J˜Jšœ œœœ˜2Jšœœ˜ šœœ˜)šœœœ ˜DJšœ˜Jšœ œ˜ Jšœ ˜ J˜J˜ Jšœ˜Jšœ˜—Jšœ˜—Jšœ#œ˜FJšœ3˜3Jšœ1˜1Jšœ!˜!Jš œœœ.œœ˜—Jšœ7˜7JšœT˜TJšœœ6œœ˜ˆJšœXœœ˜–Jšœœ˜8Jšœ˜Jšœ:˜:Jšœ˜Jšœ™˜™Jšœ˜ Jšœ˜—šžœ˜Jš œœœœœœ˜}Jšœ.˜.J˜Jšœ œœœ˜0Jšœœœœ˜&Jšœœ˜Jšœ œ˜Jšœœ˜Jšœœ˜Jšœ$œ ˜HJšœ3˜3Jšœ2˜2Jšœ˜Jšœ!˜!Jš œœœ+œœ ˜•Jšœ8˜8JšœCœ˜_šœ˜Jšœœ6œœ ˜vJšœœœ œ˜NJšœ œ ˜Jšœ œ˜#Jšœ˜Jšœ˜—Jšœ˜JšœSœœ ˜’Jšœ ˜ Jšœ.˜.Jšœ˜Jšœ˜Jšœ˜ Jšœ˜—šž œ˜Jš œœœœœœ˜‚Jšœ*˜*Jšœ"œ˜DJšœbœœ˜ŸJšœ˜Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜ Jšœ˜—šž œ˜Jš œœœœœœ˜‚Jšœ*˜*Jšœ œ˜Jšœ"œ˜DJšœœ-˜7Jšœœœ,œ4˜sJšœJœœ˜‡Jšœ˜Jšœ˜Jšœ&˜&Jšœ ˜ Jšœ ˜ Jšœ(˜(Jšœ˜ Jšœ˜—šž œ˜Jš œœœœœœ˜}Jšœ(˜(Jšœ ˜ Jšœ˜Jšœœ˜Jšœ œ˜Jšœœ˜Jšœœœœ˜ Jšœœœœ˜!Jšœœ˜Jšœ!œ˜BJšœœ˜:Jšœœ˜+šœ˜Jšœœ˜0Jšœœ˜(Jšœœœœ˜LJšœ œ ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ˜šœœ˜Jšœœ˜Jšœ œ˜Jšœ&œœ˜cJšœ ˜ Jšœ˜—šœœ œ˜Jšœœ˜Jšœ œ˜Jšœ˜—šœ˜Jšœœœ˜PJšœ&˜&Jšœ˜Jšœœ˜&Jšœ2˜2JšœDœœ˜‚Jšœ˜—Jšœ˜Jšœ˜J˜Jšœ˜Jšœ˜Jšœ˜ Jšœ˜—šž œ˜Jš œœœœœœ˜xJšœ&˜&Jšœ"˜"Jšœœœ˜Jšœ œ˜@Jšœœ˜Jšœ5œ˜:šœ˜ Jšœ(œ˜DJš˜Jšœ˜——šœ˜šž œ˜Jšœ$˜$Jšœœ˜>šœœ˜Jšœ$œœ˜^Jšœ˜—Jšœœg˜ošœœFœ˜SJšœ4œœ˜nJšœ˜—šœœ)˜KJšœ$œœ˜^—Jšœ˜Jšœ˜Jšœ˜J˜Jšœ˜Jšœ8˜8Jšœ˜ Jšœ˜—šž œ˜Jšœ#˜#Jšœ˜Jšœ œ˜=Jšœ(˜(Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜ Jšœ˜—šž œ˜J˜Jšœ˜Jšœ˜ Jšœ˜—šž œ˜J˜Jšœ˜Jšœ˜ Jšœ˜—šž œ˜Jšœœœœ˜(Jšœœ˜ Jšœ(˜(Jšœ!œ˜BJšœ0˜0Jš œ!œ0œœ'œœ˜ΨJšœ7˜7JšœN˜NJš œœœ/œœ˜†šœ˜J˜#Jšœ(˜(šœ˜ J˜Jšœ-œ˜IJšœ˜——Jšœ˜Jšœ˜ Jšœ˜—šžœ˜ Jšœœœ˜Jšœ!˜!Jšœ˜ Jšœ˜—šž œ˜Jšœ˜Jšœ˜ Jšœ˜—šž œ˜Jšœ"˜"Jšœœ˜Jšœœ˜*šœ˜Jšœ1œ˜5Jšœ1œ˜5Jšœ/œ˜3Jšœ-œ˜1Jšœ/œ˜3Jšœ-œ˜1Jšœœ˜—Jšœ˜ Jšœ˜J˜—šžœœ˜Jšœ8œœœ˜WJ˜—šžœœ˜Jšœ8œœœ˜WJ˜—šž œœ*œ˜DJšœœœ˜(Jšœ œ%˜3Jšœ8˜:Jšœ=˜BJšœ˜J˜—šžœœ*œ˜FJšœœœ˜(Jšœ œ%˜3Jšœ8˜:Jšœ.˜.Jšœ?˜EJšœ ˜"Jšœ˜J˜—šœœ œœ˜+Jšœ,˜,Jšœ4˜4JšœO˜OJšœ:˜:Jšœ;˜;JšœB˜BJšœ;˜;Jšœ5˜5Jšœ(˜(Jšœ\˜\JšœF˜FJšœD˜DJšœE˜EJšœC˜CJšœZ˜ZJšœB˜BJšœ)˜)Jšœ<˜