DIRECTORY AISFileFormat, AISIO, Args, Basics, CtBasic, CtDispatch, CtFile, CtMap, CtMod, FileNames, FS, Imager, ImagerBox, ImagerColor, ImagerPixel, ImagerPixelArray, ImagerSample, IO, Process, Rope, SF, ViewerClasses; CtFileCommandsImpl: CEDAR PROGRAM IMPORTS AISIO, Args, Basics, CtBasic, CtDispatch, CtFile, CtMap, CtMod, FileNames, FS, Imager, ImagerColor, ImagerPixel, ImagerPixelArray, ImagerSample, IO, Process, Rope, SF ~ BEGIN AISInfo: TYPE ~ AISIO.Info; SampleMaps: TYPE ~ CtBasic.SampleMaps; SampleMap: TYPE ~ ImagerSample.SampleMap; ROPE: TYPE ~ Rope.ROPE; ctSaveUsage: ROPE ~ "Ct Save [-w ] [-wi] [-wp] Save the entire color display image to disk. If -wi option, interactively select area to save. If -wp option, then use last specified (-w or -wi) box. If 24 bits, '-red.ais', '-grn.ais', '-blu.ais' are appended to name for the appropriate file."; CtSave: CtDispatch.CtProc ~ { ENABLE AISIO.Error => {error ฌ reason; GOTO Bad}; placement: AISIO.Placement ฌ NEW[AISFileFormat.PlacementPart ฌ [ Basics.HFromCard16[maps.x], Basics.HFromCard16[maps.y], Basics.HFromCard16[maps.w], Basics.HFromCard16[maps.h]]]; name: ROPE ฌ Args.GetRope[cmd]; affect ฌ [[0, 0], [0, 0]]; IF name = NIL THEN RETURN[error: "no name"]; SELECT maps.nChannels FROM 1 => { IO.PutFL[cmd.out, "saving [%g, %g] to [%g, %g] (xywh: %g %g %g %g) %g . . . ", LIST[IO.int[maps.x], IO.int[maps.y], IO.int[maps.box.max.f], IO.int[maps.box.max.s], IO.int[maps.x], IO.int[maps.y], IO.int[maps.w], IO.int[maps.h], IO.rope[name]]]; AISIO.Write[FileNames.ResolveRelativePath[name], maps[0].map, placement]; }; 3 => { names: ARRAY [0..3) OF ROPE ฌ CtFile.GetColorAISNames[name]; IO.PutFL[cmd.out, "saving [%g, %g] to [%g, %g] (xywh: %g %g %g %g)", LIST[IO.int[maps.x], IO.int[maps.y], IO.int[maps.x], IO.int[maps.y], IO.int[maps.w], IO.int[maps.h], IO.int[maps.box.max.f], IO.int[maps.box.max.s]]]; FOR n: NAT IN [0..3) DO IO.PutF1[cmd.out, " %g . . . ", IO.rope[names[n]]]; AISIO.Write[FileNames.ResolveRelativePath[names[n]], maps[n].map, placement]; ENDLOOP; }; ENDCASE; IO.PutRope[cmd.out, "done\n"]; EXITS Bad => NULL; }; ctViewUsage: ROPE ~ "Ct View [option] Display the named, un-scaled image file in a viewer. if too large, the image is clipped to a viewer when first displayed. Options: -clear clear the color display first -center center the image within the viewer -noPlace otherwise, place image at original location -cmap load the specified color map -w display image in this window -wi display image in selected box -a if AIS file, read data from this box."; CtView: CtDispatch.CtProc ~ { name, clear, cmap, center, noPlace, x, y, w, h: Args.Arg; [name, clear, cmap, center, noPlace, x, y, w, h] ฌ Args.ArgsGet[cmd, "%s-clear%b-cmap%s-center%b-noPlace%b-a%iiii" ! Args.Error => {error ฌ reason; CONTINUE}]; affect ฌ [[0, 0], [0, 0]]; IF error # NIL THEN RETURN ELSE { EachName: PROC [fullFName: ROPE] RETURNS [continue: BOOL ฌ TRUE] ~ { GetInfoAndMap: PROC [name: ROPE] RETURNS [info: AISInfo, map: SampleMap] ~ { map ฌ AISIO.Read[name, info ฌ AISIO.ReadInfo[name]]; IF x.ok AND y.ok AND w.ok AND h.ok THEN map ฌ ImagerSample.ZeroOrigin[ImagerSample.Clip[map, [[y.int, x.int], [y.int+h.int, x.int+w.int]]]]; }; GetMinAndSize: PROC [r, g, b, bw: SampleMap, placement: AISIO.Placement] RETURNS [size, srcMin, dstMin: SF.Vec ฌ [0, 0]] ~ { IF r # NIL THEN size ฌ SF.Max[size, ImagerSample.GetSize[r]]; IF g # NIL THEN size ฌ SF.Max[size, ImagerSample.GetSize[g]]; IF b # NIL THEN size ฌ SF.Max[size, ImagerSample.GetSize[b]]; IF bw # NIL THEN size ฌ SF.Max[size, ImagerSample.GetSize[bw]]; dstMin ฌ maps.box.min; SELECT TRUE FROM center.ok => { IF maps.h > size.s THEN dstMin.s ฌ (maps.h-size.s)/2 ELSE srcMin.s ฌ (size.s-maps.h)/2; IF maps.w > size.f THEN dstMin.f ฌ (maps.w-size.f)/2 ELSE srcMin.f ฌ (size.f-maps.w)/2; }; placement # NIL AND NOT noPlace.bool => { dstMin ฌ [ Basics.Card16FromH[placement.yBottom], Basics.Card16FromH[placement.xLeft]]; IF NOT SF.In[dstMin, maps.box] THEN dstMin ฌ maps.box.min; }; ENDCASE; size ฌ [MIN[size.s, maps.h-dstMin.s], MIN[size.f, maps.w-dstMin.f]]; }; r, g, b, bw: SampleMap ฌ NIL; size, srcMin, dstMin: SF.Vec; rInfo, gInfo, bInfo, bwInfo: AISInfo; fileInfo: CtFile.FileInfo ฌ CtFile.Parse[fullFName]; Process.CheckForAbort[]; SELECT fileInfo.type FROM ip => IO.PutRope[cmd.out, "Interpress files not supported\n"]; bw => { [bwInfo, bw] ฌ GetInfoAndMap[fullFName]; [size, srcMin, dstMin] ฌ GetMinAndSize[NIL, NIL, NIL, bw, bwInfo.placement]; ImagerSample.BasicTransfer[maps[0].map, bw, dstMin, srcMin, size]; affect.max ฌ SF.Max[affect.max, size]; }; color => { [rInfo, r] ฌ GetInfoAndMap[fileInfo.names[0]]; [gInfo, g] ฌ GetInfoAndMap[fileInfo.names[1]]; [bInfo, b] ฌ GetInfoAndMap[fileInfo.names[2]]; SELECT maps.bpp FROM 8 => { pm: ImagerPixel.PixelMap ฌ ImagerPixel.MakePixelMap[r, g, b]; pa: ImagerPixelArray.PixelArray ฌ ImagerPixelArray.FromPixelMap[ pm, pm.box, [down, right]]; op: ImagerColor.ColorOperator ฌ ImagerColor.NewColorOperatorRGB[255]; delta: Imager.VEC ฌ IF center.ok THEN [(maps.h-pa.sSize)/2, (maps.w-pa.fSize)/2] ELSE [0, maps.h-pa.sSize]; context ฌ CtBasic.ContextFromSampleMaps[maps]; Imager.DrawSampledColor[context, pa, op,, delta]; affect.max ฌ SF.Max[affect.max, [pa.sSize, pa.fSize]]; }; 24 => { [size, srcMin, dstMin] ฌ GetMinAndSize[r, b, b, NIL, rInfo.placement]; ImagerSample.BasicTransfer[maps[0].map, r,,, size]; ImagerSample.BasicTransfer[maps[1].map, g,,, size]; ImagerSample.BasicTransfer[maps[2].map, b,,, size]; affect.max ฌ SF.Max[affect.max, size]; }; ENDCASE; }; ENDCASE => { IO.PutF1[cmd.out, "bad file type: %g\n", IO.rope[fullFName]]; GOTO Bad; }; EXITS Bad => error ฌ " "; }; IF cmap.ok AND NOT CtMap.Load[cmap.rope] THEN RETURN[error: Rope.Concat["Can't load ", cmap.rope]]; IF clear.bool THEN CtBasic.FillMaps[maps, 0, 0, 0, 0]; name.rope ฌ FS.ExpandName[ IF Rope.Find[name.rope, "/"] = -1 AND Rope.Find[name.rope, ">"] = -1 THEN Rope.Concat[wDir, name.rope] ELSE FileNames.ResolveRelativePath[name.rope]].fullFName; IF Rope.Find[name.rope, "*"] = -1 THEN [] ฌ EachName[name.rope] ELSE FS.EnumerateForNames[name.rope, EachName, wDir]; }; }; ctDumpToAISUsage: ROPE ~ "Ct DumpToAIS [-size ] [-header] [-separate] [-ascii] [-gbr] [-mono] Decode the named dump file into new AIS file(s) (one file if -mono, else three). The dump file is assumed 8 (mono) or 24 (rgb) bits per pixel, with no header If -separate, pixels are expected as all rrr.... then ggg.... then bbb.... else, pixels are expected as rgbrgbrgb.... If -header, then a header is expected, containing the number of channels (typically 1 or 3), the width, and the height. If -head is not given, then width and height must be specified. If -ascii, the data is interpreted as ascii integers, rather than binary If -gbr file contains green, then blue, then red order"; CtDumpToAIS: CtDispatch.CtProc ~ { dump, aisName, w, h, hdr, ascii, sep, gbr, mono: Args.Arg; [dump, aisName, w, h, hdr, ascii, sep, gbr, mono] ฌ Args.ArgsGet[cmd, "%ss-size%ii-header%b-ascii%b-separate%b-gbr%b-mono%b" ! Args.Error => {error ฌ reason; CONTINUE}]; IF hdr.ok AND (w.ok OR h.ok) THEN RETURN; IF NOT hdr.ok AND (NOT w.ok OR NOT h.ok) THEN RETURN; IF error # NIL THEN RETURN ELSE { ENABLE CtFile.Error => {error ฌ reason; GOTO Bad}; maps: SampleMaps; IF hdr.ok THEN maps ฌ CtFile.ReadDumpFile[dump.rope, NIL, ascii.ok, 0, 0, 0, NOT sep.ok] ELSE { nChans: INT ฌ IF mono.ok THEN 1 ELSE 3; maps ฌ CtBasic.CreateMaps[8*nChans, 0, 0, w.int, h.int]; maps ฌ CtFile.ReadDumpFile[dump.rope, maps, ascii.ok, nChans, w.int, h.int, ~sep.ok]; }; IF gbr.ok AND maps.bpp = 24 THEN { r: SampleMap ฌ maps[2].map; g: SampleMap ฌ maps[0].map; b: SampleMap ฌ maps[1].map; maps[0].map ฌ r; maps[1].map ฌ g; maps[2].map ฌ b; }; CtFile.WriteMapsToAIS[maps, aisName.rope]; EXITS Bad => IO.PutRope[cmd.out, error]; }; }; ctPseudoTo24Usage: ROPE ~ "Ct PseudoTo24 Convert the current 8 bpp display to 24 bpp AIS file triplet."; CtPseudoTo24: CtDispatch.CtProc ~ { ENABLE AISIO.Error => {error ฌ reason; GOTO Bad}; IF maps.bpp # 8 THEN RETURN[error: "this option only for 8 bpp displays"] ELSE { m: SampleMap ฌ ImagerSample.NewSampleMap[[[maps.y, maps.x], [maps.h, maps.w]], 8]; cmap: CtMap.Cmap ฌ CtMap.Read[]; exts: ARRAY [0..3) OF ROPE ฌ ["-red.ais", "-grn.ais", "-blu.ais"]; IO.PutFL[cmd.out, "saving [%g, %g] to [%g, %g] (xywh: %g %g %g %g)", LIST[IO.int[maps.x], IO.int[maps.y], IO.int[maps.x], IO.int[maps.y], IO.int[maps.w], IO.int[maps.h], IO.int[maps.box.max.f], IO.int[maps.box.max.s]]]; FOR n: NAT IN [0..3) DO name: ROPE ฌ Rope.Concat[Args.GetRope[cmd], exts[n]]; ImagerSample.Transfer[m, maps[0].map]; CtMod.Indirect[m, CtMap.GetTable[cmap, n], maps.box]; IO.PutF1[cmd.out, " %g . . . ", IO.rope[name]]; AISIO.Write[FileNames.ResolveRelativePath[name], m]; ENDLOOP; IO.PutRope[cmd.out, "done\n"]; }; EXITS Bad => RETURN; }; CtDispatch.RegisterCtOp["File IO:", NIL, NIL]; CtDispatch.RegisterCtOp["Save", CtSave, ctSaveUsage]; CtDispatch.RegisterCtOp["View", CtView, ctViewUsage]; CtDispatch.RegisterCtOp["DumpToAIS", CtDumpToAIS, ctDumpToAISUsage, FALSE]; CtDispatch.RegisterCtOp["PseudoTo24", CtPseudoTo24, ctPseudoTo24Usage]; END. CtDispatch.RegisterCtOp["Dump", CtDump, ctDumpUsage]; ctDumpUsage: ROPE ~ "Ct Dump [-withHeader] [width] [height] Display the named, dump file in a viewer. If with header, the file must start with the following 16 bit numbers: a magic number # channels (1 or 3) width height then followed by pixel data (for 24 bpp, r, g, b . . .) If no header, file presumed 8 bpp and width, height needed."; CtDump: CtDispatch.CtProc ~ { widthA, heightA, nameA, withHeaderA: Args.Arg; [widthA, heightA, nameA, withHeaderA] ฌ Args.ArgsGet[cmd, "[ii%s-withHeader%b" ! Args.Error => {msg ฌ reason; CONTINUE}]; IF msg # NIL THEN RETURN[$Failure, msg]; IF withHeaderA.bool THEN [] ฌ CtFile.ReadDumpFile[nameA.rope, maps] ELSE { Action: PROC [line: ImagerSample.SampleBuffer] ~ TRUSTED { box: ImagerSample.Box ฌ ImagerSample.GetBox[maps[0].map]; w: INT ฌ box.max.f-box.min.f; FOR y: NAT IN [0..heightA.int) DO Process.CheckForAbort[]; FOR x: NAT IN [0..widthA.int) DO line.samples[x] ฌ IO.GetByte[s]; ENDLOOP; IF y IN [box.min.s..box.max.s] THEN ImagerSample.PutSamples[maps[0].map, [y, box.min.f],, line, box.min.f, w]; ENDLOOP; }; s: IO.STREAM ฌ FS.StreamOpen[nameA.rope ! FS.Error => GOTO Bad]; IF s = NIL THEN RETURN[$Failure, "Can't open file."]; ImagerSample.DoWithScratchSamples[widthA.int, Action]; EXITS Bad => RETURN[$Failure, "Can't open file."]; }; };  CtFileCommandsImpl.mesa Copyright ำ 1990, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, December 7, 1992 4:34 pm PST Andrew Glassner July 9, 1991 1:21 pm PDT Types Write: Display to File Read: File to Display ctViewUsage: ROPE ~ "Ct View [option] Display the named image file in a viewer. The complete file name should be given unless the image is 24 bits, in which case only the base name should be given. Images are un-scaled, and clipped to a viewer when first displayed. Options: -clear clear the color display first -center center the image on the color display -noPlace otherwise, place where originally saved -cmap load the specified color map -w display image in this box -wi display image in selected box -a if ais file, read data from this box."; ENABLE AISIO.Error => {IO.PutF[cmd.out, reason]; GOTO Bad}; CtMap.Dither[]; Note: even though CtView, as a DispatchProc, is supplied with a context, we perform the following to ensure that the current context is associated with the current colormap, which may have changed since the creation of the context: msg _ CtFile.ViewFile[maps, fullFName, center.bool, noPlace.bool, x, y, w, h]; Dump File Conversion Pseudo to 24bpp Conversion Start Code ส ป–"cedarcode" style•NewlineDelimiter ™™Jšœ ฯeœ6™BJ™)J™(—J˜Jš ฯk œžœFžœOžœžœ˜ฺJ˜šัblnœžœž˜!Jš žœžœFžœDžœž˜ฎ—J˜Jšœž˜headšฯl™Jšœ žœžœ˜Jšœžœ˜(Jšœžœ˜,Jšžœžœžœ˜—š ™šœ žœ˜J˜ฆJ˜—šะbnœ˜Jšžœžœžœ˜1šœ žœ žœ ˜@Jšœ7˜7Jšœ9˜9—Jšœžœ˜J˜Jšžœžœžœžœ˜,šžœž˜šœ˜JšžœMžœžœžœžœžœžœžœžœžœžœ˜๔JšžœD˜IJ˜—˜Jšœžœžœžœ!˜<šžœB˜DJšžœžœžœžœžœžœžœžœžœ˜–—šžœžœžœž˜Jšžœžœ˜3JšžœH˜MJšžœ˜—J˜—Jšžœ˜—Jšžœ˜Jšžœžœ˜J˜——š ™šœ žœ™J™ีJ™—šœ žœ˜J˜ํJ˜—šกœ˜J˜9˜2šœ?˜?Jšœ!žœ˜,——J˜šžœ ž˜Jšžœž˜ šžœ˜š ฯnœžœ žœžœ žœžœ˜DJšžœžœ žœžœ™;š ข œฯsžฃœžœžœ$˜LJšœžœžœ˜4š žœžœžœžœž˜'J˜d—J˜—šข œžœ%žœ ˜HJšžœžœ˜/J˜Jšžœžœžœžœ$˜=Jšžœžœžœžœ$˜=Jšžœžœžœžœ$˜=Jšžœžœžœžœ%˜?J˜šžœžœž˜šœ ฃœฃœ˜šžœ˜Jšžœ˜!Jšžœ˜"—šžœ˜Jšžœ˜!Jšžœ˜"—J˜—šœ žœžœžœ˜)˜ J˜&J˜%—Jšžœžœžœžœ˜:J˜—Jšžœ˜—Jšœžœžœ˜DJ˜—Jšœžœ˜Jšœžœ˜J˜%J˜4J˜šžœž˜Jšœžœ6˜>˜J˜(Jšœ'žœžœžœ˜LJšœ'ฃœฃœฃœ˜BJšœ žœ˜&J˜—šœ ˜ J˜.J˜.J˜.šžœ ž˜˜J˜=˜@J˜—Jšœฃœฃœฃœ%˜Ešœžœžฃœ ˜ Jšžฃœฃœ˜/Jšžœ˜—J™J–0.0 24 .div 1 1 textColor™HJ–0.0 24 .div 1 1 textColor™IJ–0.0 24 .div 1 1 textColor™DJ–0.0 24 .div 1 1 textColor™J˜.Jšœ8˜8Jšœ žœ'˜6J˜—˜Jšœ0žœ˜FJšœ'ฃœฃœ˜3Jšœ'ฃœฃœ˜3Jšœ'ฃœฃœ˜3Jšœ žœ˜&J˜—Jšžœ˜—J˜—šžœ˜ Jšžœ'žœ˜=Jšžœ˜ J˜——JšœN™NJšžœ˜J˜—šžœ žœžœ˜(Jšžœžœ/˜:—Jšžœ žœ$˜6šœ žœ ˜šžœ žœ˜DJšžœ˜!Jšžœ5˜9——šžœ˜!Jšžœ˜Jšžœžœ.˜5—J˜——J˜——š ™šœžœ˜J˜แJ˜—šก œ˜"J˜:˜3šœH˜HJšœ!žœ˜,——Jš žœžœžœžœžœ˜)Jšžœžœžœžœžœžœžœžœ˜5šžœ ž˜Jšžœž˜ šžœ˜Jšžœ"žœ˜2Jšœ˜šžœ˜ Jšžœ'žœžœ˜Nšžœ˜Jš œžœžœ žœžœ˜'J˜8Jšœฃœฃœฃœฃœ ฃœฃœฃœฃžœ˜UJ˜——šžœžœžœ˜"J˜J˜J˜J˜J˜J˜J˜—Jšœ*˜*Jšžœžœ˜(J˜——J˜——š ™šœžœ˜J˜_J˜—šก œ˜#Jšžœžœžœ˜1šžœ ˜Jšžœžœ/˜:šžœ˜J˜RJ˜ Jšœžœžœžœ(˜BšžœB˜DJšžœžœžœžœžœžœžœžœžœ˜–—šžœžœžœž˜Jšœžœ+˜5J˜&J˜5Jšžœžœ ˜/Jšžœ/˜4Jšžœ˜—Jšžœ˜J˜——Jšžœžœ˜J˜——š  ™ Jšœ$žœžœ˜.J˜5J˜5JšœDžœ˜KJšœG˜GJ˜—Jšžœ˜™˜5J˜—šœ žœ˜J˜ุJ˜—šกœ˜J˜.˜NJšœžœ˜*—Jšžœžœžœžœ˜(šžœ˜Jšžœ+˜/šžœ˜šกœžœ%žœ˜:J˜9Jšœžœ˜šžœžœžœž˜!J˜Jš žœžœžœžœžœ žœ˜Jšžœžœž˜#JšœJ˜J—Jšžœ˜—J˜—Jš œžœžœžœžœ žœ˜@Jšžœžœžœžœ˜5J˜6Jšžœžœ˜2˜J˜J˜——————…—)ไ9ณ