DIRECTORY Atom, Basics, FS USING [StreamOpen], Imager, ImagerBackdoor USING [Clipper, IntKey, RealKey], ImagerColor, ImagerColorDefs USING [Color, ColorOperator, ConstantColor, SampledColor], ImagerColorOperator, ImagerColorOperatorPrivate USING [ColorOperatorImpl, ColorOperatorImplRep, SampleMap], ImagerColorPrivate USING [ConstantColorImpl, ConstantColorImplRep], ImagerFont USING [Font, XChar, XStringProc], ImagerInterpressFragment USING [VectorProc], ImagerOps, ImagerPath USING [Filter, PathProc], ImagerPixelArray USING [GetSamples, MaxSampleValue, PixelArray, UnsafeGetBits], ImagerPixelMap, ImagerPrivate USING [Class, ClassRep], ImagerSample USING [GetPointer, NewBuffer, Sample, SampleBuffer, UnsafePutF, UnsafeSamples], ImagerTransformation, IO USING [Close, Error, GetIndex, PutBlock, PutRope, SetLength, STREAM, UnsafePutBlock], IPMaster USING [PutByte, PutIdentifier, PutInt, PutIntBytes, PutName, PutOp, PutReal, PutSequence, PutString], PrincOpsUtils USING [LongZero], Real, Rope USING [ROPE], Vector2 USING [VEC]; ImagerInterpressFragmentImpl: CEDAR PROGRAM IMPORTS Atom, FS, Imager, ImagerPath, ImagerPixelArray, ImagerSample, ImagerTransformation, IO, IPMaster, PrincOpsUtils EXPORTS Imager, ImagerColorDefs, ImagerInterpressFragment ~ BEGIN OPEN IPMaster; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; VectorProc: TYPE ~ ImagerInterpressFragment.VectorProc; BYTE: TYPE ~ Basics.BYTE; VEC: TYPE ~ Vector2.VEC; Rectangle: TYPE ~ ImagerTransformation.Rectangle; Transformation: TYPE ~ ImagerTransformation.Transformation; PathProc: TYPE ~ ImagerPath.PathProc; Color: TYPE ~ ImagerColorDefs.Color; ConstantColor: TYPE ~ ImagerColorDefs.ConstantColor; SampledColor: TYPE ~ ImagerColorDefs.SampledColor; ConstantColorImpl: TYPE ~ ImagerColorPrivate.ConstantColorImpl; ConstantColorImplRep: PUBLIC TYPE ~ ImagerColorPrivate.ConstantColorImplRep; Sample: TYPE ~ ImagerSample.Sample; PixelArray: TYPE ~ ImagerPixelArray.PixelArray; ColorOperator: TYPE ~ ImagerColorDefs.ColorOperator; ColorOperatorImpl: TYPE ~ ImagerColorOperatorPrivate.ColorOperatorImpl; ColorOperatorImplRep: PUBLIC TYPE ~ ImagerColorOperatorPrivate.ColorOperatorImplRep; Font: TYPE ~ ImagerFont.Font; XChar: TYPE ~ ImagerFont.XChar; XStringProc: TYPE ~ ImagerFont.XStringProc; IntKey: TYPE ~ ImagerBackdoor.IntKey; RealKey: TYPE ~ ImagerBackdoor.RealKey; Clipper: TYPE ~ ImagerBackdoor.Clipper; Context: TYPE ~ Imager.Context; Class: TYPE ~ ImagerPrivate.Class; ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager firstIPForm: NAT ~ 100; endIPForm: NAT ~ 1000; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD[ stream: STREAM, frame: Frame _ NIL, buffer: REF TEXT _ NIL, pushVectorActive: BOOL _ FALSE, getTDone: BOOL _ FALSE, getTForm: NAT _ firstIPForm, savedSize: NAT _ 0 ]; Frame: TYPE ~ REF FrameRep; FrameRep: TYPE ~ RECORD [size: NAT, entries: SEQUENCE max: NAT OF REF]; topFrameSize: NAT ~ 50; Ref: TYPE ~ REF Rep; Rep: PUBLIC TYPE ~ RECORD[ page: INT _ 0, context: Imager.Context _ NIL, data: Data _ NIL ]; Create: PUBLIC PROC [fileName: ROPE, header: ROPE] RETURNS [Ref] ~ { stream: STREAM ~ FS.StreamOpen[fileName, $create]; IF header = NIL THEN header _ "Interpress/Xerox/3.0 "; RETURN[CreateFromStream[stream, header]]; }; CreateFromStream: PUBLIC PROC [stream: STREAM, header: ROPE] RETURNS [Ref] ~ { frame: Frame ~ NEW[FrameRep[topFrameSize] _ [size: 0, entries: ]]; buffer: REF TEXT ~ NEW[TEXT[200]]; data: Data ~ NEW[DataRep _ [stream: stream, frame: frame, buffer: buffer]]; IO.PutRope[stream, header]; PutOp[stream, beginBlock]; -- begin master RETURN[NEW[Rep _ [page: 0, context: NIL, data: data]]]; }; StreamFromRef: PUBLIC PROC [self: Ref] RETURNS [stream: STREAM] ~ { data: Data ~ self.data; RETURN [data.stream]; }; PushInt: PUBLIC PROC [self: Ref, n: INT] ~ { data: Data ~ self.data; stream: STREAM ~ data.stream; PutInt[stream, n]; }; PushVector: PUBLIC PROC [self: Ref, vectorProc: VectorProc] ~ { data: Data ~ self.data; stream: STREAM ~ data.stream; count: INT _ 0; putIdentifier: PROC [identifier: ATOM] ~ { PutIdentifier[stream, Atom.GetPName[identifier]]; count _ count + 1; }; putString: PROC [rope: Rope.ROPE] ~ { PutString[stream, rope]; count _ count + 1; }; putInt: PROC [int: INT] ~ { PutInt[stream, int]; count _ count + 1; }; putReal: PROC [real: REAL] ~ { PutReal[stream, real]; count _ count + 1; }; putTransformation: PROC [t: Transformation] ~ { PutTransformation[stream, t]; count _ count + 1; }; putVector: PROC [v: PROC] ~ { save: INT ~ count; count _ 0; v[]; PutInt[stream, count]; PutOp[stream, makevec]; count _ save + 1; }; putImageOp: PROC [action: PROC [Imager.Context]] ~ { ERROR Imager.Error[[code: $unimplemented, explanation: "Cannot put image operations in Interpress fragment."]]; }; IF data.pushVectorActive THEN ERROR Imager.Error[[$InvalidOperationSequence, "Cannot call PushVector recursively"]]; data.pushVectorActive _ TRUE; vectorProc[putIdentifier, putString, putInt, putReal, putTransformation, putVector, putImageOp]; PutInt[stream, count]; PutOp[stream, makevec]; data.pushVectorActive _ FALSE; }; PushPixelArray: PUBLIC PROC [self: Ref, pa: PixelArray] ~ { data: Data ~ self.data; MakePixelArray[data, pa] }; PushColorOperator: PUBLIC PROC [self: Ref, op: ColorOperator] ~ { data: Data ~ self.data; MakeColorOperator[data, op] }; Close: PUBLIC PROC [self: Ref] ~ { data: Data ~ self.data; Finish[self]; IO.Close[data.stream]; }; Finish: PUBLIC PROC [self: Ref] ~ { data: Data ~ self.data; stream: STREAM ~ data.stream; PutOp[stream, endBlock]; -- end master }; MakeVec: PROC [stream: STREAM, n: INT] ~ { PutInt[stream, n]; PutOp[stream, makevec]; }; PutVec: PROC [stream: STREAM, v: VEC] ~ { PutReal[stream, v.x]; PutReal[stream, v.y]; }; PutVecI: PROC [stream: STREAM, x, y: INTEGER] ~ { PutInt[stream, x]; PutInt[stream, y]; }; PutRectangle: PROC [stream: STREAM, r: Rectangle] ~ { PutReal[stream, r.x]; PutReal[stream, r.y]; PutReal[stream, r.w]; PutReal[stream, r.h]; }; PutRectangleI: PROC [stream: STREAM, x, y, w, h: INTEGER] ~ { PutInt[stream, x]; PutInt[stream, y]; PutInt[stream, w]; PutInt[stream, h]; }; PutTransformation: PROC [stream: STREAM, m: Transformation] ~ { f: ImagerTransformation.FactoredTransformation ~ ImagerTransformation.Factor[m]; depth: NAT _ 0; IF f.r1#0 THEN { PutReal[stream, f.r1]; PutOp[stream, rotate]; depth _ depth+1; }; IF f.s.x#f.s.y THEN { PutVec[stream, f.s]; PutOp[stream, scale2]; depth _ depth+1; } ELSE IF f.s.x#1 THEN { PutReal[stream, f.s.x]; PutOp[stream, scale]; depth _ depth+1; }; IF f.r2#0 THEN { PutReal[stream, f.r2]; PutOp[stream, rotate]; depth _ depth+1; }; IF f.t.x#0 OR f.t.y#0 THEN { PutVec[stream, f.t]; PutOp[stream, translate]; depth _ depth+1; }; WHILE depth>1 DO PutOp[stream, concat]; depth _ depth-1 ENDLOOP; IF depth=0 THEN { PutInt[stream, 1]; PutOp[stream, scale] }; }; PutPath: PROC [stream: STREAM, path: PathProc, close: PROC] ~ { p0: VEC _ [0, 0]; moveTo: PROC [p: VEC] ~ { PutVec[stream, p]; PutOp[stream, moveto]; p0 _ p; }; lineTo: PROC [p1: VEC] ~ { IF p1.y=p0.y THEN { PutReal[stream, p1.x]; PutOp[stream, linetox]; } ELSE IF p1.x=p0.x THEN { PutReal[stream, p1.y]; PutOp[stream, linetoy]; } ELSE { PutVec[stream, p1]; PutOp[stream, lineto]; }; p0 _ p1; }; curveTo: PROC [p1, p2, p3: VEC] ~ { PutVec[stream, p1]; PutVec[stream, p2]; PutVec[stream, p3]; PutOp[stream, curveto]; p0 _ p3; }; conicTo: PROC [p1, p2: VEC, r: REAL] ~ { PutVec[stream, p1]; PutVec[stream, p2]; PutReal[stream, r]; PutOp[stream, conicto]; p0 _ p2; }; arcTo: PROC [p1, p2: VEC] ~ { PutVec[stream, p1]; PutVec[stream, p2]; PutOp[stream, arcto]; p0 _ p2; }; ImagerPath.Filter[path: path, moveTo: moveTo, lineTo: lineTo, curveTo: curveTo, conicTo: conicTo, arcTo: arcTo, close: close]; }; PutSampleMap: PROC [stream: STREAM, map: ImagerColorOperatorPrivate.SampleMap] ~ { IF map=NIL THEN PutInt[stream, 0] ELSE { FOR i: Sample IN[0..map.size) DO PutReal[stream, map[i]] ENDLOOP; MakeVec[stream, map.size]; }; }; identity: Transformation ~ ImagerTransformation.Scale[1]; MakePixelArray: PROC [data: Data, pa: PixelArray] ~ { stream: STREAM ~ data.stream; samplesPerPixel: NAT ~ pa.samplesPerPixel; sSize: NAT ~ pa.sSize; fSize: NAT ~ pa.fSize; maxSample: Sample _ 0; bitsPerSample: NAT _ 0; translate: VEC; PutInt[stream, fSize]; -- xPixels PutInt[stream, sSize]; -- yPixels PutInt[stream, samplesPerPixel]; -- samplesPerPixel IF samplesPerPixel = 1 THEN { maxSample _ ImagerPixelArray.MaxSampleValue[pa, 0]; PutInt[stream, maxSample]; PutInt[stream, 1]; -- samplesInterleaved; use 1 for compatibility with older interpress versions } ELSE { FOR i: NAT IN[0..samplesPerPixel) DO m: Sample ~ ImagerPixelArray.MaxSampleValue[pa, i]; PutInt[stream, m]; maxSample _ MAX[maxSample, m]; ENDLOOP; MakeVec[stream, samplesPerPixel]; -- maxSampleValue PutInt[stream, 0]; -- samplesInterleaved }; translate _ ImagerTransformation.Factor[pa.m].t; ImagerTransformation.ApplyPostTranslate[pa.m, [-translate.x, pa.sSize-translate.y]]; -- normalize the pixel array transformation to have a [0, sSize] translation component PutTransformation[stream, pa.m]; -- m bitsPerSample _ SELECT maxSample FROM 1 => 1, IN[2..255] => 8, IN[256..LAST[CARDINAL]] => 16, ENDCASE => ERROR; -- can't handle it yet IF bitsPerSample=1 AND samplesPerPixel = 1 THEN TRUSTED { bigWordsPerLine: INT ~ (INT[fSize]+31)/32; paddedBitsPerLine: INT ~ bigWordsPerLine*32; wordsPerLine: INT ~ paddedBitsPerLine/Basics.bitsPerWord; bytesPerLine: INT ~ paddedBitsPerLine/8; dataByteCount: INT ~ bytesPerLine*sSize; rawWords: REF Basics.RawWords ~ NEW[Basics.RawWords[wordsPerLine]]; rawBase: LONG POINTER ~ @rawWords[0]; PrincOpsUtils.LongZero[where: rawBase, nwords: wordsPerLine]; PutSequence[stream, $sequencePackedPixelVector, 4+dataByteCount]; PutIntBytes[stream, 1, 2]; -- 1 bit per sample PutIntBytes[stream, fSize, 2]; -- number of pixels per scan line, excluding padding IO.SetLength[stream, IO.GetIndex[stream]+dataByteCount ! IO.Error => CONTINUE]; -- pre-allocate a portion of the file FOR s: NAT IN[0..sSize) DO ImagerPixelArray.UnsafeGetBits[pa: pa, i: 0, s: s, f: 0, dst: [word: rawBase, bit: 0], dstBpl: paddedBitsPerLine, width: fSize, height: 1, srcFunc: null, dstFunc: null]; IO.UnsafePutBlock[stream, [base: rawBase, startIndex: 0, count: bytesPerLine]]; ENDLOOP; } ELSE { bytesPerSample: NAT ~ bitsPerSample/8; bytesPerLine: INT ~ INT[bytesPerSample]*fSize; buffer: ImagerSample.SampleBuffer ~ ImagerSample.NewBuffer[1, fSize]; block: REF TEXT ~ NEW[TEXT[bytesPerLine]]; dataByteCount: INT ~ INT[samplesPerPixel]*INT[sSize]*INT[fSize]*bytesPerSample; IO.SetLength[stream, IO.GetIndex[stream]+dataByteCount ! IO.Error => CONTINUE]; -- pre-allocate a portion of the file PutSequence[stream, $sequenceLargeVector, 1+dataByteCount]; PutByte[stream, bytesPerSample]; FOR i: NAT IN[0..samplesPerPixel) DO FOR s: NAT IN[0..sSize) DO ImagerPixelArray.GetSamples[pa: pa, i: i, s: s, f: 0, buffer: buffer, count: fSize]; TRUSTED { samples: ImagerSample.UnsafeSamples ~ ImagerSample.GetPointer[buffer, 0, 0, fSize]; base: LONG POINTER ~ LOOPHOLE[block, LONG POINTER]+SIZE[TEXT[0]]; ImagerSample.UnsafePutF[samples: samples, count: fSize, s: 0, f: 0, base: base, wordsPerLine: 0, bitsPerSample: bitsPerSample]; }; IO.PutBlock[self: stream, block: block, startIndex: 0, count: bytesPerLine]; ENDLOOP; ENDLOOP; }; PutOp[stream, makepixelarray]; }; MakeColorOperator: PROC [data: Data, colorOperator: ColorOperator] ~ { impl: ColorOperatorImpl ~ colorOperator.impl; stream: STREAM ~ data.stream; WITH impl SELECT FROM impl: REF ColorOperatorImplRep.grayLinear => { PutReal[stream, impl.sWhite]; PutReal[stream, impl.sBlack]; PutSampleMap[stream, impl.map]; MakeVec[stream, 3]; PutName[stream, "Xerox/GrayLinear"]; }; impl: REF ColorOperatorImplRep.grayDensity => { PutReal[stream, impl.sWhite]; PutReal[stream, impl.sBlack]; PutReal[stream, impl.dBlack]; PutSampleMap[stream, impl.map]; MakeVec[stream, 4]; PutName[stream, "Xerox/GrayDensity"]; }; impl: REF ColorOperatorImplRep.grayVisual => { PutReal[stream, impl.sWhite]; PutReal[stream, impl.sBlack]; PutSampleMap[stream, impl.map]; MakeVec[stream, 3]; PutName[stream, "Xerox/GrayVisual"]; }; impl: REF ColorOperatorImplRep.rgbLinear => { PutReal[stream, impl.maxSampleValue]; MakeVec[stream, 1]; PutName[stream, "Xerox/Research/RGBLinear"]; }; ENDCASE => ERROR Imager.Error[[code: $unimplemented, explanation: "Color operator has unknown type."]]; PutOp[stream, findcolormodeloperator]; PutOp[stream, do]; }; END. ΘImagerInterpressFragmentImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Michael Plass, June 16, 1986 1:53:16 pm PDT Tim Diebert: October 9, 1985 9:44:55 am PDT Doug Wyatt, November 21, 1985 3:14:29 pm PST Rick Beach, July 23, 1986 9:15:39 am PDT impl: REF ColorOperatorImplRep.map => { FOR i: Sample IN[0..impl.size) DO MakeColor[data, impl[i]] ENDLOOP; MakeVec[stream, impl.size]; PutName[stream, "Xerox/Map"]; }; Κ^˜codešœ!™!Kšœ Οmœ7™BK™+K™+K™,K™(—K˜šΟk ˜ K˜K˜Kšžœžœ˜Kšœ˜Kšœžœ˜0Kšœ ˜ Kšœžœ5˜JKšœ˜Kšœžœ6˜VKšœžœ+˜CKšœ žœ˜,Kšœžœ˜,K˜ Kšœ žœ˜$Kšœžœ9˜OK˜Kšœžœ˜&Kšœ žœJ˜\Kšœ˜Kšžœžœ8žœ˜XKšœ žœ`˜nKšœžœ ˜K˜Kšœžœžœ˜Kšœžœžœ˜—K˜KšΠblœžœž˜+KšžœžœLžœ˜wKšžœ2˜9Kšœžœžœ ˜K˜Kšžœžœžœ˜Kšžœžœžœžœ˜Kšœ žœ'˜7K˜Kšžœžœ žœ˜Kšžœžœ žœ˜Kšœ žœ"˜1Kšœžœ'˜;Kšœ žœ˜%K˜Kšœžœ˜$Kšœžœ!˜4Kšœžœ ˜2Kšœžœ(˜?Kšœžœžœ+˜LK˜Kšœžœ˜#Kšœ žœ˜/K˜Kšœžœ!˜4Kšœžœ0˜GKšœžœžœ3˜TK˜Kšœžœ˜Kšœžœ˜Kšœ žœ˜+K˜Kšœžœ˜%Kšœ žœ˜'Kšœ žœ˜'K˜Kšœ žœ˜Kšœžœ˜"šœ žœžœΟc˜CK˜—Kšœ žœ˜Kšœ žœ˜Kšœžœžœ ˜šœ žœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ˜Kšœžœžœ˜Kšœ žœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœ˜K˜—Kšœžœžœ ˜šœ žœžœžœ žœžœžœžœ˜GK˜—šœžœ˜K˜—Kšœžœžœ˜šœžœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœ ž˜Kšœ˜—K˜š Οnœžœžœ žœžœžœ ˜DKšœžœžœ˜2Kšžœ žœžœ"˜6Kšžœ#˜)K˜K˜—š ‘œžœžœ žœ žœžœ ˜NKšœžœ0˜BKš œžœžœžœžœ˜"Kšœ žœ;˜KKšžœ˜Kšœ ˜*Kšžœžœžœ˜7Kšœ˜K˜—š ‘ œžœžœ žœ žœ˜CKšœ˜Kšžœ˜Kšœ˜K˜—š‘œžœžœžœ˜,K˜Kšœžœ˜Kšœ˜Kšœ˜K™—š‘ œžœžœ(˜?K˜Kšœžœ˜Kšœžœ˜šœžœžœ˜*Kšœ Οtœ’œ ’œ˜1Kšœ˜Kšœ˜—šœ žœ žœ˜%K˜Kšœ˜Kšœ˜—šœžœžœ˜Kšœ˜Kšœ˜Kšœ˜—šœ žœžœ˜Kšœ˜Kšœ˜Kšœ˜—šœžœ˜/Kšœ˜Kšœ˜Kšœ˜—šœ žœžœ˜Kšœžœ ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ žœ žœ˜4Kšžœj˜oKšœ˜—šžœž˜KšžœQ˜V—Kšœžœ˜Kšœ`˜`Kšœ˜Kšœ˜Kšœžœ˜Kšœ˜K™—š‘œžœžœ ˜;K˜K˜Kšœ˜K™—š‘œžœžœ#˜AK˜Kšœ˜Kšœ˜K™—š‘œžœžœ˜"Kšœ˜Kšœ ˜ Kšžœ˜K˜K˜—š‘œžœžœ˜#Kšœ˜Kšœžœ˜Kšœ  ˜&K˜K˜—K™š‘œžœ žœžœ˜*Kšœ*˜*Kšœ˜K˜—š‘œžœ žœžœ˜)Kšœ+˜+Kšœ˜K˜—š‘œžœ žœžœ˜1Kšœ%˜%Kšœ˜K˜—š‘ œžœ žœ˜5KšœW˜WKšœ˜K˜—š‘ œžœ žœžœ˜=KšœK˜KKšœ˜K˜—š‘œžœ žœ˜?KšœP˜PKšœžœ˜šžœžœ˜Kšœ-˜-Kšœ˜Kšœ˜—šžœ žœ˜Kšœ+˜+Kšœ˜K˜—šžœžœ žœ˜Kšœ-˜-Kšœ˜K˜—šžœžœ˜Kšœ-˜-Kšœ˜Kšœ˜—šžœ žœ žœ˜Kšœ.˜.Kšœ˜Kšœ˜—Kšžœ žœ(žœ˜@Kšžœ žœ-˜