DIRECTORY ColorEditOps, FS USING [StreamOpen], IO USING [Close, GetChar, EndOf, PutChar, RIS, ROS, RopeFromROS, STREAM], SampleMapOps USING [Clear, DoWithScratch, Fill, GetSample], SelectRegions USING [ApplyTRC, nullRectangle, TRCSequence, TRCSequenceRep]; ColorEditOpsImpl: CEDAR PROGRAM IMPORTS FS, IO, SampleMapOps, SelectRegions EXPORTS ColorEditOps ~ BEGIN OPEN ColorEditOps; LogApply: PUBLIC PROC [trc: REF TRC, sm: SampleMap, extent: Rectangle] RETURNS [rope: ROPE] ~ { stream: IO.STREAM ~ IO.ROS[]; FOR i: NAT IN [0..256) DO IO.PutChar[self: stream, char: VAL[trc[i]]]; ENDLOOP; SaveExtentOfMaskToStream[stream: stream, mask: sm, extent: extent]; rope _ IO.RopeFromROS[self: stream]; }; ApplyLog: PUBLIC PROC [changeLog: ROPE, sa: SampleArray] ~ { ApplyLogAction: PROC [sm: SampleMap] ~ { stream: IO.STREAM ~ IO.RIS[rope: changeLog]; trcs: SelectRegions.TRCSequence ~ NEW[SelectRegions.TRCSequenceRep[sa.n]]; trc: REF TRC ~ NEW[TRC]; extent: Rectangle; FOR i: NAT IN [0..trcs.n) DO trcs[i] _ trc; ENDLOOP; UNTIL IO.EndOf[self: stream] DO FOR i: NAT IN [0..256) DO trc[i] _ LOOPHOLE[IO.GetChar[self: stream]]; ENDLOOP; extent _ ReadExtentOfMaskFromStream[stream: stream, mask: sm]; SelectRegions.ApplyTRC[sm, sa, trcs, extent]; ENDLOOP; }; SampleMapOps.DoWithScratch[sSize: sa.sSize, fSize: sa.fSize, bitsPerSample: 1, action: ApplyLogAction]; }; extentFilePassword: CARDINAL ~ 30346; SaveExtentOfMask: PUBLIC PROC [mask: SampleMap, extent: Rectangle, fileName: ROPE] ~ { file: IO.STREAM ~ FS.StreamOpen[fileName: fileName, accessOptions: create]; SaveExtentOfMaskToStream[file, mask, extent]; IO.Close[self: file]; }; ReadExtentOfMask: PUBLIC PROC [mask: SampleMap, fileName: ROPE] RETURNS [extent: Rectangle] ~ { file: IO.STREAM ~ FS.StreamOpen[fileName: fileName]; extent _ ReadExtentOfMaskFromStream[file, mask]; }; SaveExtentOfMaskToStream: PUBLIC PROC [stream: IO.STREAM, mask: SampleMap, extent: Rectangle] ~ { PutCardinal: PROC [cardinal: CARDINAL] ~ { IO.PutChar[self: stream, char: VAL[cardinal/256]]; IO.PutChar[self: stream, char: VAL[cardinal MOD 256]]; }; bitsPerSample: [1..1] ~ mask.bitsPerSample; currentValue: CARDINAL _ 0; currentCount: CARDINAL _ 0; PutCardinal[extentFilePassword]; PutCardinal[mask.sSize]; PutCardinal[mask.fSize]; PutCardinal[extent.sMin]; PutCardinal[extent.sMax]; PutCardinal[extent.fMin]; PutCardinal[extent.fMax]; IF extent#SelectRegions.nullRectangle THEN { FOR s: CARDINAL IN [extent.sMin .. extent.sMax] DO FOR f: CARDINAL IN [extent.fMin .. extent.fMax] DO sample: CARDINAL ~ SampleMapOps.GetSample[sampleMap: mask, index: [s: s, f: f]]; SELECT TRUE FROM sample#currentValue => { PutCardinal[currentCount]; currentCount _ 1; currentValue _ 1 - currentValue; }; currentCount = CARDINAL.LAST-1 => { PutCardinal[CARDINAL.LAST]; currentCount _ 0; currentValue _ 1 - currentValue; }; ENDCASE => currentCount _ currentCount+1; ENDLOOP; ENDLOOP; }; IF currentCount#0 THEN PutCardinal[currentCount]; PutCardinal[extentFilePassword]; --Pad with the password }; ReadExtentOfMaskFromStream: PUBLIC PROC [stream: IO.STREAM, mask: SampleMap] RETURNS [extent: Rectangle] ~ { GetCardinal: PROC RETURNS [CARDINAL] ~ { hi: CARDINAL ~ LOOPHOLE[IO.GetChar[self: stream]]; lo: CARDINAL ~ LOOPHOLE[IO.GetChar[self: stream]]; RETURN [hi*256 + lo]; }; bitsPerSample: [1..1] ~ mask.bitsPerSample; currentValue: CARDINAL _ 0; currentCount: CARDINAL _ 0; IF GetCardinal[] # extentFilePassword THEN ERROR; IF GetCardinal[] # mask.sSize THEN ERROR; IF GetCardinal[] # mask.fSize THEN ERROR; extent.sMin _ GetCardinal[]; extent.sMax _ GetCardinal[]; extent.fMin _ GetCardinal[]; extent.fMax _ GetCardinal[]; SampleMapOps.Clear[mask]; IF extent=SelectRegions.nullRectangle THEN RETURN; currentCount _ GetCardinal[]; FOR s: CARDINAL IN [extent.sMin .. extent.sMax] DO f: CARDINAL _ extent.fMin; WHILE f ~> extent.fMax DO count: CARDINAL _ MIN[currentCount, extent.fMax+1-f]; IF currentValue=1 THEN SampleMapOps.Fill[dest: [sampleMap: mask, start: [s: s, f: f], size: [s: 1, f: count]], value: 1]; f _ f+count; currentCount _ currentCount - count; IF currentCount=0 THEN { currentValue _ 1-currentValue; currentCount _ GetCardinal[]; }; ENDLOOP; ENDLOOP; IF currentCount # extentFilePassword THEN ERROR; }; END. ςColorEditOpsImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Eric Nickell, January 7, 1986 8:43:23 am PST Converts the parameters for an Apply into a rope Apply the logged information currently in data.changeLog Κͺ˜™Icodešœ Οmœ1™K˜-Kšžœ˜—K˜—K–V[sSize: CARDINAL, fSize: CARDINAL, bitsPerSample: [0..16], action: PROC [...]]˜gK˜—Lšœžœ ˜%š œžœžœ0žœ˜VKšœžœžœžœ7˜KK˜-K–'[self: STREAM, abort: BOOL _ FALSE]šžœ˜K˜—š  œžœžœžœžœ˜_Kšœžœžœžœ ˜4Kšœ0˜0K˜—š  œžœžœ žœžœ)˜a– [fileName: ROPE, accessOptions: FS.AccessOptions _ read, streamOptions: FS.StreamOptions _ (5)[TRUE, TRUE, TRUE, TRUE, TRUE], keep: CARDINAL _ 1B (1), createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ [vmPagesPerBuffer: 8, nBuffers: 2], extendFileProc: FS.ExtendFileProc, wantedCreatedTime: GMT _ --{UnknownError[sig: 3021B, msg: 177777B]}--, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL]š  œžœ žœ˜*K–[self: STREAM, char: CHAR]šžœžœ˜2K–[self: STREAM, char: CHAR]šžœžœ žœ˜6K˜—K˜+Kšœžœ˜Kšœžœ˜K˜Kšœ ˜ K˜K˜K˜K˜K˜K˜K˜šžœ#žœ˜,šžœžœžœž˜2šžœžœžœž˜2Kšœžœ@˜Pšžœžœž˜šœ˜K˜K˜Kšœ ˜ Kšœ˜—šœžœžœ˜#Kšœ žœžœ˜K˜Kšœ ˜ Kšœ˜—Kšžœ"˜)—Kšžœ˜—Kšžœ˜—Kšœ˜—Kšžœžœ˜1Kšœ"Οc˜9K˜—š  œžœžœ žœžœžœ˜lš  œžœžœžœ˜(K–[self: STREAM]šœžœžœžœ˜2Kšœžœžœžœ˜2Kšžœ˜K˜—K˜+Kšœžœ˜Kšœžœ˜K˜Kšžœ$žœžœ˜1Kšžœžœžœ˜)Kšžœžœžœ˜)K˜K˜K˜K˜K˜K˜Kšžœ$žœžœ˜2K˜K˜šžœžœžœž˜2Kšœžœ˜šžœž˜Kšœžœžœ ˜5Kšžœžœc˜yK˜ K˜$šžœžœ˜K˜K˜Kšœ˜—Kšžœ˜—Kšžœ˜—Kšžœ#žœžœ˜0K˜——K˜Kšžœ˜—…—–2