<> <> <> <<>> DIRECTORY ImagerPixelMap, PDFileFormat, PDFileReader, Commander, IO, Rope; CheckPDImpl: CEDAR PROGRAM IMPORTS PDFileReader, Commander, IO, Rope ~ BEGIN Break: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ OR char = '; THEN RETURN [break]; IF char = ' OR char = ' OR char = ', OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; BitTable: TYPE ~ REF BitTableRep; BitTableRep: TYPE ~ ARRAY [0..10000) OF PACKED ARRAY [0..16) OF InitFalseBoolean; InitFalseBoolean: TYPE ~ BOOLEAN _ FALSE; TypePDCommand: Commander.CommandProc ~ { stream: IO.STREAM _ IO.RIS[cmd.commandLine]; name: Rope.ROPE _ stream.GetTokenRope[Break].token; reader: PDFileReader.Handle _ PDFileReader.Open[name]; out: IO.STREAM _ cmd.out; bitTable: BitTable _ NEW[BitTableRep]; AlreadyPrinted: PROC [loadAddress: INT] RETURNS [BOOLEAN] ~ { IF loadAddress < 0 THEN RETURN [TRUE] ELSE { address: LONG CARDINAL _ loadAddress; IF bitTable[address/16][address MOD 16] THEN RETURN [TRUE] ELSE {bitTable[address/16][address MOD 16] _ TRUE; RETURN [FALSE]}; }; }; quiet: BOOLEAN _ Rope.Find[cmd.commandLine, "QUIET"] >= 0; out.Put[IO.refAny[NEW[PDFileFormat.Herald _ reader.herald]]]; out.PutChar['\n]; DO ref: REF _ PDFileReader.Get[reader]; WITH ref SELECT FROM stateChange: PDFileReader.StateChange => { SELECT stateChange.whatChanged FROM imageStart => { out.PutRope["StartImage "]; out.Put[IO.refAny[NEW[PDFileFormat.StartImage _ reader.image]]]; out.PutChar['\n]; }; imageEnd => out.PutRope["EndImage\n"]; priorityChange => out.PutF["Priority %g\n", IO.int[reader.priority]]; colorChange => { out.PutF["Color Change %g addr %g", IO.refAny[NEW[PDFileReader.ColorType _ reader.colorType]], IO.int[reader.colorTileLoadAddress]]; IF quiet OR reader.colorTileLoadAddress < 0 OR AlreadyPrinted[reader.colorTileLoadAddress] THEN NULL ELSE { tile: ImagerPixelMap.Tile ~ PDFileReader.ColorTileFromLoad[reader, reader.colorTileLoadAddress]; out.PutF[" [sOrigin: %g, fOrigin: %g, sSize: %g, fSize: %g, phase: %g]\n", IO.int[tile.sOrigin], IO.int[tile.fOrigin], IO.int[tile.sSize], IO.int[tile.fSize], IO.int[tile.phase]]; }; }; bandChange => out.PutRope["New Band\n"]; loadChange => out.PutF["Load %g(%g)\n", IO.int[stateChange.loadChangeStart], IO.int[stateChange.loadChangeLength]]; documentEnd => EXIT; ENDCASE => ERROR; }; maskSamples: PDFileReader.MaskSamples => { out.PutRope[" MaskSamples"]; IF maskSamples.loadAddress # -1 THEN { out.PutF["Ref %g", IO.int[maskSamples.loadAddress]]; }; out.PutF[" [%g, %g, %g, %g]\n", IO.int[maskSamples.samples.fOrigin + maskSamples.samples.sMin], IO.int[maskSamples.samples.fOrigin + maskSamples.samples.fMin], IO.int[maskSamples.samples.sSize], IO.int[maskSamples.samples.fSize] ]; }; maskRunGroup: PDFileReader.MaskRunGroup => TRUSTED { p: LONG POINTER TO PDFileFormat.Run _ maskRunGroup.pointer; out.PutRope[" MaskRunGroup"]; IF maskRunGroup.loadAddress # -1 THEN { out.PutF["Ref %g", IO.int[maskRunGroup.loadAddress]]; }; out.PutF[" [%g, %g, %g, %g] %g runs:\n", IO.int[maskRunGroup.sMin], IO.int[maskRunGroup.fMin], IO.int[maskRunGroup.sSize], IO.int[maskRunGroup.fSize], IO.int[maskRunGroup.runCount] ]; IF quiet OR AlreadyPrinted[maskRunGroup.loadAddress] THEN NULL ELSE { FOR i: INT IN [0..maskRunGroup.runCount) DO out.PutF[" %g(%g)", IO.int[p.fMin], IO.int[p.fSize]]; IF p.lastRun THEN out.PutChar['\n]; p _ p + SIZE[PDFileFormat.Run]; ENDLOOP; }; }; ENDCASE => { out.PutRope[" "]; out.Put[IO.refAny[ref]]; out.PutChar['\n]; }; ENDLOOP; PDFileReader.Close[reader]; cmd.out.PutRope[" Done.\n"]; }; StatsRep: TYPE ~ RECORD [ priorityChange: INT _ 0, colorChange: INT _ 0, bandChange: INT _ 0, loadChange: INT _ 0, maskRectangle: INT _ 0, maskTrapezoid: INT _ 0, maskRunGroup: INT _ 0, maskRunGroupRef: INT _ 0, maskSamples: INT _ 0, maskSamplesRef: INT _ 0, colorSamples: INT _ 0, deviceCommand: INT _ 0 ]; CheckPDCommand: Commander.CommandProc ~ { stream: IO.STREAM _ IO.RIS[cmd.commandLine]; name: Rope.ROPE _ stream.GetTokenRope[Break].token; reader: PDFileReader.Handle _ PDFileReader.Open[name]; out: IO.STREAM _ cmd.out; stats: REF StatsRep _ NEW[StatsRep _ []]; out.Put[IO.refAny[NEW[PDFileFormat.Herald _ reader.herald]]]; out.PutChar['\n]; DO ref: REF _ PDFileReader.Get[handle: reader, scanning: TRUE]; WITH ref SELECT FROM stateChange: PDFileReader.StateChange => { SELECT stateChange.whatChanged FROM imageStart => { out.PutRope["StartImage "]; out.Put[IO.refAny[NEW[PDFileFormat.StartImage _ reader.image]]]; out.PutChar['\n]; stats^ _ []; }; documentEnd => EXIT; imageEnd => { out.PutRope["EndImage "]; out.Put[IO.refAny[stats]]; out.PutRope["\n\n"]; }; priorityChange => { stats.priorityChange _ stats.priorityChange + 1; }; colorChange => { stats.colorChange _ stats.colorChange + 1; }; bandChange => { stats.bandChange _ stats.bandChange + 1; }; loadChange => { stats.loadChange _ stats.loadChange + 1; }; ENDCASE => NULL; }; maskRectangle: PDFileReader.MaskRectangle => { stats.maskRectangle _ stats.maskRectangle + 1; }; maskTrapezoid: PDFileReader.MaskTrapezoid => { stats.maskTrapezoid _ stats.maskTrapezoid + 1; }; maskRunGroup: PDFileReader.MaskRunGroup => { IF maskRunGroup.loadAddress >= 0 THEN stats.maskRunGroupRef _ stats.maskRunGroupRef + 1 ELSE stats.maskRunGroup _ stats.maskRunGroup + 1 }; maskSamples: PDFileReader.MaskSamples => { IF maskSamples.loadAddress >= 0 THEN stats.maskSamplesRef _ stats.maskSamplesRef + 1 ELSE stats.maskSamples _ stats.maskSamples + 1 }; colorSamples: PDFileReader.ColorSamples => { stats.colorSamples _ stats.colorSamples + 1; }; deviceCommand: PDFileReader.DeviceCommand => { stats.deviceCommand _ stats.deviceCommand + 1; }; ENDCASE => NULL; ENDLOOP; PDFileReader.Close[reader]; cmd.out.PutRope[" Done.\n"]; }; Commander.Register["CheckPD", CheckPDCommand, "Check a PD file"]; Commander.Register["TypePD", TypePDCommand, "Type a PD file"]; END.