<> <> <> <<>> DIRECTORY Basics, Real, GridModulation, ImagerPixelMap, Rope, FontTuningParameters, Convert, FS, IO; FontTuningParametersImpl: CEDAR PROGRAM IMPORTS Basics, Real, ImagerPixelMap, Rope, Convert, FS, IO EXPORTS FontTuningParameters ~ BEGIN OPEN FontTuningParameters; BadToken: PUBLIC SIGNAL [fileName: ROPE, token: ROPE, location: INT] ~ CODE; parameterFimeNameExtension: ROPE _ ".fontTune"; Load: PUBLIC PROC [fileName: ROPE] RETURNS [Ref] ~ { new: Ref ~ NEW[Rep]; meanIntensity: REF ARRAY [0..512) OF REAL ~ NEW[ARRAY [0..512) OF REAL]; stdDev: REF ARRAY [0..512) OF REAL ~ NEW[ARRAY [0..512) OF REAL]; occurrences: REF ARRAY [0..512) OF REAL ~ NEW[ARRAY [0..512) OF REAL]; minMeanIntensity: REAL _ 9999999999.9; maxMeanIntensity: REAL _ 0; printerModelRadius: [0..1] _ 0; ReadModel: PROC [fileName: ROPE] ~ { stream: IO.STREAM _ FS.StreamOpen[fileName: fileName]; token: REF TEXT _ NEW[TEXT[20]]; Match: PROC [key: ROPE] RETURNS [BOOL] ~ TRUSTED { RETURN [key.Equal[LOOPHOLE[token]]] }; tokenKind: IO.TokenKind _ tokenERROR; tokenStartIndex: INT _ 0; stackTop: [0..30] _ 0; stack: ARRAY [0..30) OF REAL; Push: PROC [real: REAL] ~ {stack[stackTop] _ real; stackTop _ stackTop + 1}; Pop: PROC RETURNS [real: REAL] ~ {stackTop _ stackTop - 1; real _ stack[stackTop]}; PopInt: PROC RETURNS [int: INT] ~ {stackTop _ stackTop - 1; int _ Real.RoundLI[stack[stackTop]]}; tokenArg: ROPE _ NIL; tokenArgStart: INT _ 0; GetToken: PROC ~ { charsSkipped: INT _ 0; tokenStartIndex _ IO.GetIndex[stream]; [tokenKind: tokenKind, token: token, charsSkipped: charsSkipped] _ stream.GetCedarToken[buffer: token, flushComments: TRUE]; tokenStartIndex _ tokenStartIndex + charsSkipped; }; GetKernel: PROC ~ { radius: NAT _ PopInt[]; neighbors: DeviceRectangle ~ [-radius, -radius, 2*radius+1, 2*radius+1]; new.comparisonKernel _ ImagerPixelMap.Create[4, neighbors]; FOR s: INT DECREASING IN [-radius..radius] DO FOR f: INT DECREASING IN [-radius..radius] DO intensity: [0..255] _ PopInt[]; new.comparisonKernel.Fill[[s,f,1,1], intensity]; ENDLOOP; ENDLOOP; }; c: [0..512) _ 0; GetToken[]; UNTIL tokenKind = tokenEOF DO myArg: ROPE _ tokenArg; SELECT tokenKind FROM tokenID => { SELECT TRUE FROM Match["gridEvenness"] => new.gridParam.evenness _ Pop[]; Match["gridPenaltyWeight"] => new.gridParam.penaltyWeight _ Pop[]; Match["gridEdgePinning"] => new.gridParam.edgePinning _ Pop[]; Match["gridMaxOutputDeviation"] => new.gridParam.maxOutputDeviation _ Pop[]; Match["gridReductionFactor"] => new.gridReductionFactor _ PopInt[]; Match["comparisonKernel"] => GetKernel[]; Match["minIntensity"] => [] _ Pop[]; Match["maxIntensity"] => [] _ Pop[]; Match["printerModelRadius"] => printerModelRadius _ PopInt[]; Match["noiseWeight"] => new.noiseWeight _ Pop[]; Match["encoding"] => c _ PopInt[]; Match["aveIntensity"] => meanIntensity[c] _ Pop[]; Match["stdDev"] => stdDev[c] _ Pop[]; Match["occurrences"] => occurrences[c] _ PopInt[]; Match["swathWidth"] => new.swathWidth _ PopInt[]; Match["tuningPasses"] => new.tuningPasses _ PopInt[]; Match["Load"] => {ReadModel[Rope.Concat[myArg, parameterFimeNameExtension]]; myArg _ NIL}; ENDCASE => { IF myArg # NIL THEN SIGNAL BadToken[fileName, Rope.FromRefText[token], tokenStartIndex]; myArg _ NIL; tokenArg _ Rope.FromRefText[token]; tokenArgStart _ tokenStartIndex; }; }; tokenDECIMAL, tokenOCTAL, tokenHEX => TRUSTED {Push[Convert.CardFromWholeNumberLiteral[LOOPHOLE[token]]]}; tokenREAL => TRUSTED {Push[Convert.RealFromRope[LOOPHOLE[token]]]}; ENDCASE => SIGNAL BadToken[fileName, Rope.FromRefText[token], tokenStartIndex]; IF myArg # NIL THEN SIGNAL BadToken[fileName, Rope.FromRefText[token], tokenStartIndex]; GetToken[]; ENDLOOP; IO.Close[stream]; }; SaveSequences: PROC ~ { d: NAT ~ 2*printerModelRadius+1; n: NAT ~ Basics.BITSHIFT[1, d*d]; new.printerModelNeighborhood _ [-printerModelRadius, -printerModelRadius, d, d]; new.intensity _ NEW[RealSequenceRep[n]]; FOR i: NAT IN [0..n) DO new.intensity[i] _ meanIntensity[i] ENDLOOP; new.noisePenalty _ NEW[RealSequenceRep[n]]; FOR i: NAT IN [0..n) DO new.noisePenalty[i] _ stdDev[i] ENDLOOP; new.occurrences _ NEW[RealSequenceRep[n]]; FOR i: NAT IN [0..n) DO new.occurrences[i] _ occurrences[i] ENDLOOP; }; <> <> <> <<(intensity-minMeanIntensity) / (maxMeanIntensity-minMeanIntensity);>> <> <<};>> ReadModel[fileName]; SaveSequences[]; <> <> <> <> <> RETURN [new] }; Store: PUBLIC PROC [ref: Ref, fileName: ROPE] ~ { io: IO.STREAM _ FS.StreamOpen[fileName, $create]; kradius: [0..1] _ SELECT ref.comparisonKernel.Window FROM [0,0,1,1] => 0, [-1,-1,3,3] => 1, ENDCASE => ERROR; pmRadius: [0..1] _ SELECT ref.printerModelNeighborhood FROM [0,0,1,1] => 0, [-1,-1,3,3] => 1, ENDCASE => ERROR; io.PutF["%g gridEvenness\n%g gridPenaltyWeight\n%g gridEdgePinning\n%g gridMaxOutputDeviation\n", IO.real[ref.gridParam.evenness], IO.real[ref.gridParam.penaltyWeight], IO.real[ref.gridParam.edgePinning], IO.real[ref.gridParam.maxOutputDeviation] ]; io.PutF["%g gridReductionFactor\n", IO.int[ref.gridReductionFactor]]; FOR s: INT IN [-kradius..kradius] DO FOR f: INT IN [-kradius..kradius] DO io.Put[IO.int[ref.comparisonKernel.GetPixel[s,f]]]; io.PutChar[IF f = kradius THEN '\n ELSE ' ]; ENDLOOP; ENDLOOP; io.PutF["%g comparisonKernel\n", IO.int[kradius]]; io.PutF["%g printerModelRadius\n", IO.int[pmRadius]]; io.PutF["%g swathWidth\n", IO.int[ref.swathWidth]]; io.PutF["%g tuningPasses\n", IO.int[ref.tuningPasses]]; io.PutF["%g noiseWeight\n", IO.real[ref.noiseWeight]]; FOR c: INT IN [0..ref.intensity.length) DO io.PutF["%03BB encoding %g aveIntensity %g stdDev %g occurrences\n", IO.int[c], IO.real[ref.intensity[c]], IO.real[ref.noisePenalty[c]], IO.int[Real.RoundLI[ref.occurrences[c]]] ]; ENDLOOP; io.Close; }; END.