DitherImpl.mesa
Mik Lamming September 15, 1983 9:13 am

DIRECTORY
AIS    USING [Error],
ColorMap   USING [GetColor, SetRGBColor],
DitherAIS  USING [Squash, Stretch, UserMapProc, UserUnmapProc],
FileIO    USING [Open, OpenFailed],
Graphics    USING [Color, Context, DrawBox, DrawImage, SetCP, SetColor],
GraphicsBasic USING [Color],
GraphicsColor USING [RGBToColor],
GraphicsOps  USING [NewAisImage],
IO     USING [Close, STREAM],
Map    USING [ColorMapSize, ColorTable, GetIndex, PalTable, Restore],
Menus    USING [AppendMenuEntry, CreateMenu, CreateEntry, MenuProc],
Rope    USING [Cat, ROPE],
ViewerClasses  USING [GetProc, PaintProc, Viewer, ViewerClass, ViewerClassRec],
ViewerOps   USING [ComputeColumn, CreateViewer, PaintViewer, RegisterViewerClass],
ViewerTools  USING [GetSelectionContents];

DitherImpl: MONITOR
IMPORTS AIS, ColorMap, DitherAIS, FileIO, Graphics, GraphicsColor, GraphicsOps, IO, Map, Menus, Rope, ViewerOps, ViewerTools = BEGIN
MapFileStem:Rope.ROPE ← "Std";
FileToDisplay:Rope.ROPENIL;
MapTable: Map.ColorTable;
MapPal: Map.PalTable;
DitherPaint: ViewerClasses.PaintProc = TRUSTED {
IF whatChanged#NIL THEN
ShowMap[context]
ELSE {
IF FileToDisplay = NIL THEN
RETURN;
Graphics.SetCP[self:context, x:50, y:0];
Graphics.DrawImage[self:context, image:GraphicsOps.NewAisImage[FileToDisplay], raw:TRUE];
};
};
SetColorMap: PROCEDURE [PMapFileStem:Rope.ROPE] = {
fileName:Rope.ROPE ← Rope.Cat[PMapFileStem, ".tab"];
IF FileExists[fileName] THEN {
MapFileStem ← PMapFileStem;
[MapTable, MapPal] ← Map.Restore[fileName];
};
FOR palix:CARDINAL IN [0..MapPal.size) DO
OPEN MapPal[palix];
ColorMap.SetRGBColor[palix, r,g,b];
ENDLOOP
};
ShowMap: PROCEDURE [context:Graphics.Context] = {
palix:CARDINAL ← 0;
FOR i:CARDINAL IN [0..7] DO
FOR j:CARDINAL IN [0..7] DO
FOR k:CARDINAL IN [0..3] DO
OPEN MapPal[palix];
Graphics.SetColor[context, GraphicsColor.RGBToColor[r,g,b]];
Graphics.DrawBox[context, [k*120+j*15+50, i*50+50, k*120+65+j*15, i*50+100]];
palix ← palix + 1;
IF palix=MapPal.size THEN
RETURN
ENDLOOP;
ENDLOOP;
ENDLOOP;
};
DitherGet: ViewerClasses.GetProc = TRUSTED {
RETURN [NIL]
};
FileExists: PROCEDURE [fileName:Rope.ROPE] RETURNS [answer:BOOLEAN←TRUE] = {
s:IO.STREAM ← FileIO.Open[fileName:fileName, createOptions:oldOnly
! FileIO.OpenFailed => TRUSTED {
answer←FALSE;
GOTO notThere;
}];
IO.Close[s];
EXITS
notThere => NULL;
};
Dither: ENTRY Menus.MenuProc = TRUSTED {
filestem:Rope.ROPE ← ViewerTools.GetSelectionContents[];
redFilename:Rope.ROPE ← Rope.Cat[filestem, "-red.ais"];
blueFilename:Rope.ROPE ← Rope.Cat[filestem, "-blu.ais"];
greenFilename:Rope.ROPE ← Rope.Cat[filestem, "-grn.ais"];
FSFilename:Rope.ROPE ← Rope.Cat[filestem, "-", MapFileStem, ".ais"];
ditherViewer.name ← Rope.Cat["Dithering: ", filestem, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
IF NOT FileExists[FSFilename] THEN {
DitherAIS.Squash[redFilename, greenFilename, blueFilename, FSFilename, MyMap
! AIS.Error => {
ditherViewer.name ← Rope.Cat[FSFilename, " - Bad file name", " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
GOTO giveUp}];
};
FileToDisplay ← FSFilename;
ditherViewer.name ← Rope.Cat[FSFilename, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, client, FALSE, NIL];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
EXITS
giveUp => NULL;
};
Quantize: ENTRY Menus.MenuProc = TRUSTED {
filestem:Rope.ROPE ← ViewerTools.GetSelectionContents[];
redFilename:Rope.ROPE ← Rope.Cat[filestem, "-red.ais"];
blueFilename:Rope.ROPE ← Rope.Cat[filestem, "-blu.ais"];
greenFilename:Rope.ROPE ← Rope.Cat[filestem, "-grn.ais"];
FSFilename:Rope.ROPE ← Rope.Cat[filestem, "-Q", MapFileStem, ".ais"];
ditherViewer.name ← Rope.Cat["Quantizing: ", filestem, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
IF NOT FileExists[FSFilename] THEN {
DitherAIS.Squash[redFilename, greenFilename, blueFilename, FSFilename, MyQuan
! AIS.Error => {
ditherViewer.name ← Rope.Cat[FSFilename, " - Bad file name", " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
GOTO giveUp}];
};
FileToDisplay ← FSFilename;
ditherViewer.name ← Rope.Cat[FSFilename, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, client, FALSE, NIL];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
EXITS
giveUp => NULL;
};
Separate: ENTRY Menus.MenuProc = TRUSTED {
filestem:Rope.ROPE ← ViewerTools.GetSelectionContents[];
redFilename:Rope.ROPE ← Rope.Cat[filestem, "fs-red.ais"];
blueFilename:Rope.ROPE ← Rope.Cat[filestem, "fs-blu.ais"];
greenFilename:Rope.ROPE ← Rope.Cat[filestem, "fs-grn.ais"];
FSFilename:Rope.ROPE ← Rope.Cat[filestem, "-", MapFileStem, ".ais"];
ditherViewer.name ← Rope.Cat["Separating: ", filestem, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
IF FileExists[FSFilename] THEN {
DitherAIS.Stretch[redFilename, greenFilename, blueFilename, FSFilename, MyUnMap
! AIS.Error => {
ditherViewer.name ← Rope.Cat[FSFilename, " - Bad file name", " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
GOTO giveUp}];
};
ditherViewer.name ← Rope.Cat[FSFilename, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
EXITS
giveUp => NULL;
};
QSeparate: ENTRY Menus.MenuProc = TRUSTED {
filestem:Rope.ROPE ← ViewerTools.GetSelectionContents[];
redFilename:Rope.ROPE ← Rope.Cat[filestem, "Qfs-red.ais"];
blueFilename:Rope.ROPE ← Rope.Cat[filestem, "Qfs-blu.ais"];
greenFilename:Rope.ROPE ← Rope.Cat[filestem, "Qfs-grn.ais"];
FSFilename:Rope.ROPE ← Rope.Cat[filestem, "-Q", MapFileStem, ".ais"];
ditherViewer.name ← Rope.Cat["Separating: ", filestem, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
IF FileExists[FSFilename] THEN {
DitherAIS.Stretch[redFilename, greenFilename, blueFilename, FSFilename, MyUnMap
! AIS.Error => {
ditherViewer.name ← Rope.Cat[FSFilename, " - Bad file name", " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
GOTO giveUp}];
};
ditherViewer.name ← Rope.Cat[FSFilename, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
EXITS
giveUp => NULL;
};
Show: ENTRY Menus.MenuProc = TRUSTED {
filestem:Rope.ROPE ← ViewerTools.GetSelectionContents[];
FSFilename:Rope.ROPE ← Rope.Cat[filestem, "-", MapFileStem, ".ais"];
IF FileExists[FSFilename] THEN {
FileToDisplay ← FSFilename;
ditherViewer.name ← Rope.Cat[FileToDisplay, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, all, FALSE, NIL];
}
ELSE {
ditherViewer.name ← Rope.Cat[FSFilename, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, caption, FALSE, NIL];
}
};
SetMap:Menus.MenuProc = TRUSTED {
SetColorMap[ViewerTools.GetSelectionContents[]];
ditherViewer.name ← Rope.Cat[FileToDisplay, " - Map: ", MapFileStem];
ViewerOps.PaintViewer[ditherViewer, all, FALSE, $MAP];
};
MyMap: DitherAIS.UserMapProc = {
rb,gb,bb:Map.ColorMapSize;
palix ← Map.GetIndex[r, g, b, MapTable];
[rb,gb,bb] ← ColorMap.GetColor[palix]; -- ought to use the table
re ← r - rb;
ge ← g - gb;
be ← b - bb;
};
MyQuan: DitherAIS.UserMapProc = {
rb,gb,bb:Map.ColorMapSize;
palix ← Map.GetIndex[r, g, b, MapTable];
[rb,gb,bb] ← ColorMap.GetColor[palix]; -- ought to use the table
re ← 0;
ge ← 0;
be ← 0;
};
MyUnMap: DitherAIS.UserUnmapProc = {
[r, g, b] ← ColorMap.GetColor[palix]; -- ought to use the table
};

MAIN PROGRAM STARTS HERE
DithertestClass:ViewerClasses.ViewerClass ← NEW[ViewerClasses.ViewerClassRec];
ditherViewer:ViewerClasses.Viewer;
DithertestClass.paint ← DitherPaint;
DithertestClass.get ← DitherGet;
ViewerOps.RegisterViewerClass[$Dither, DithertestClass];
SetColorMap[MapFileStem];
ditherViewer ← ViewerOps.CreateViewer[flavor:$Dither, info:[name:"Dither test", column:color], paint:FALSE];
ditherViewer.menu ← Menus.CreateMenu[1];
Menus.AppendMenuEntry[menu:ditherViewer.menu, entry:Menus.CreateEntry [name:"Dither", proc:Dither, fork:TRUE, documentation: "Create 8 bit dithered rgb file from 8-bit r,g and b files"], line:0];
Menus.AppendMenuEntry[menu:ditherViewer.menu, entry:Menus.CreateEntry [name:"Quantize", proc:Quantize, fork:TRUE, documentation: "Create 8 bit rgb file from 8-bit r,g and b files"], line:0];
Menus.AppendMenuEntry[menu:ditherViewer.menu, entry:Menus.CreateEntry [name:"DStretch", proc:Separate, fork:TRUE, documentation: "Create 8-bit r,g and b files from 8 bit rgb file"], line:0];
Menus.AppendMenuEntry[menu:ditherViewer.menu, entry:Menus.CreateEntry [name:"QStretch", proc:QSeparate, fork:TRUE, documentation: "Create 8-bit r,g and b files from 8 bit rgb file"], line:0];
Menus.AppendMenuEntry[menu:ditherViewer.menu, entry:Menus.CreateEntry [name:"Show", proc:Show, fork:TRUE, documentation: "Show rgb file"], line:0];
Menus.AppendMenuEntry[menu:ditherViewer.menu, entry:Menus.CreateEntry [name:"ShowMap", proc:SetMap, fork:FALSE, documentation: "Display the current color map"], line:0];
ViewerOps.ComputeColumn[column: ditherViewer.column];
END.