unit Initialization;

interface


	uses
		QuickDraw, OSIntf, PickerIntf, PrintTraps, ToolIntf, globals, Utilities, Graphics;

	procedure Init;
	procedure AllocateBuffers;
	procedure SetupMenus;
	procedure GetSettings;


implementation


{$IFC Arlo }
	procedure InitMaskNFFT;
	begin
		with FFTConfig do
			begin
				psScale := 10;			{ default is Log Scaling }
				xyScaled := false;
				useBigBufForFFT := false;
				doMeanZero := true;
				doZeroPad := false;
				doAveragePad := false;
				autoMask := false;
				autoFilter := false;
				autoPass := false;
				autoThreshold := false;
				autoInverseFFT := true;
				clipExtrema := true;
				FreqDomainOP := Multiply;
			end;
		with MaskConfig do
			begin
				maskMode := gaussian;
				percentWidth := 30;
				pixelWidth := 10;
				MinLevel := 0;
				MaxLevel := 100;
			end;
	end;
{$ENDC }

	procedure MakeCursors;
  {Generates tool cursors from tool font. Thanks to Borland for "OffScreenDrawing"}
  {and "MysteryCursor" examples in "Turbo Pascal Tutor".}
		var
			TempPort: GrafPort;
			tPort: GrafPtr;
			aRect, bRect: Rect;
			OffScreenBitMap: BitMap;
			BlankMask: Bits16;
			tool: ToolType;
			i: integer;
			TempCurH: CursHandle;
	begin
		GetPort(tPort);
		OpenPort(@TempPort);
		with OffScreenBitMap do
			begin
				baseAddr := NewPtr(2 * 16); { allocate a bit image for 16x16 cursor}
				rowBytes := 2;              { 2 bytes per row}
				SetRect(bounds, 0, 0, 16, 16);  { define usable area and coordinate systme }
			end;
		SetPortBits(OffscreenBitMap);
		for i := 0 to 15 do
			BlankMask[i] := 0;
		TextFont(ToolFont);
		TextSize(12);
		for tool := FirstTool to LastTool do
			begin
				EraseRect(OffscreenBitMap.bounds);
				MoveTo(0, 0);
				DrawChar(ToolCursorChar[tool]);
				with ToolCursor[tool] do
					begin
						BlockMove(OffscreenBitMap.BaseAddr, @data, 32);
						hotspot.h := 8;
						hotspot.v := 8;
						mask := BlankMask;
					end;
			end;
		ClosePort(@TempPort);
		SetPort(tPort);

		TempCurH := GetCursor(PickerCursorID);
		if TempCurH <> nil then
			begin
				PickerCursor := TempCurH^^;
				ToolCursor[PickerTool] := PickerCursor;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(CrossCursorPlusID);
		if TempCurH <> nil then
			begin
				CrossPlusCursor := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(CrossCursorMinusID);
		if TempCurH <> nil then
			begin
				CrossMinusCursor := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(CrossCursorID);
		if TempCurH <> nil then
			begin
				ToolCursor[SelectionTool] := TempCurH^^;
				ToolCursor[FreehandTool] := TempCurH^^;
				ToolCursor[PolygonTool] := TempCurH^^;
				ToolCursor[ruler] := TempCurH^^;
				ToolCursor[PlotTool] := TempCurH^^;
				ToolCursor[OvalSelectionTool] := TempCurH^^;
				ToolCursor[RoundedRectTool] := TempCurH^^;
				ToolCursor[AngleTool] := TempCurH^^;
				ToolCursor[PointingTool] := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(LUTCursorID);
		if TempCurH <> nil then
			begin
				LUTCursor := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(gmCursorID);
		if TempCurH <> nil then
			begin
				gmCursor := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(GrabberCursorID);
		if TempCurH <> nil then
			begin
				ToolCursor[Grabber] := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(PencilCursorID);
		if TempCurH <> nil then
			begin
				ToolCursor[Pencil] := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(GlassCursorPlusID);
		if TempCurH <> nil then
			begin
				ToolCursor[MagnifyingGlass] := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(GlassCursorMinusID);
		if TempCurH <> nil then
			begin
				GlassMinusCursor := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(BucketCursorID);
		if TempCurH <> nil then
			begin
				ToolCursor[PaintBucket] := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(WandCursorID);
		if TempCurH <> nil then
			begin
				ToolCursor[Wand] := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;

		TempCurH := GetCursor(WatchCursor);
		if TempCurH <> nil then
			begin
				watch := TempCurH^^;
				ReleaseResource(handle(TempCurH));
			end;
	end;


	procedure InitTools;
		var
			ToolTop, LinesTop, i: integer;
			Tool: ToolType;
	begin
		FirstTool := MagnifyingGlass;
		LastTool := PointingTool;
		CurrentTool := SelectionTool;
		isSelectionTool := true;
		PreviousTool := CurrentTool;
		ToolTop := 0;
		for tool := FirstTool to LastTool do
			with ToolRect[tool] do
				begin
					top := ToolTop;
					bottom := top + tmiddle;
					if odd(ord(tool) + 1) then
						left := 0
					else
						begin
							left := tmiddle;
							ToolTop := ToolTop + tmiddle;
						end;
					right := left + tmiddle;
				end;
		ToolChar[Pencil] := chr(76);
		ToolChar[SelectionTool] := chr(70);
		ToolChar[MagnifyingGlass] := chr(66);
		ToolChar[TextTool] := chr(72);
		ToolChar[Grabber] := chr(71);
		ToolChar[Brush] := chr(75);
		ToolChar[ruler] := chr(112);
		ToolChar[PaintBucket] := chr(104);
		ToolChar[AirBrushTool] := chr(74);
		ToolChar[PlotTool] := chr(94);
		ToolChar[Wand] := chr(101);
		ToolChar[Eraser] := chr(78);
		ToolChar[FreehandTool] := chr(69);
		ToolChar[PolygonTool] := chr(87);
		ToolChar[OvalSelectionTool] := chr(83);
		ToolChar[PickerTool] := chr(77);
		ToolChar[RoundedRectTool] := chr(97);
		ToolChar[LUTTool] := chr(86);
		ToolChar[AngleTool] := chr(106);
		ToolChar[PointingTool] := chr(113);
		ToolCursorChar[SelectionTool] := chr(89);
		ToolCursorChar[Pencil] := chr(76);
		ToolCursorChar[MagnifyingGlass] := chr(66);
		ToolCursorChar[TextTool] := chr(110);
		ToolCursorChar[Grabber] := chr(71);
		ToolCursorChar[brush] := chr(103);
		ToolCursorChar[ruler] := chr(89);
		ToolCursorChar[PaintBucket] := chr(89);
		ToolCursorChar[RoundedRectTool] := chr(89);
		ToolCursorChar[LUTTool] := chr(86);
		ToolCursorChar[FreehandTool] := chr(89);
		ToolCursorChar[AirbrushTool] := chr(100);
		ToolCursorChar[PolygonTool] := chr(89);
		ToolCursorChar[PlotTool] := chr(89);
		ToolCursorChar[Wand] := chr(100);
		ToolCursorChar[Eraser] := chr(68);
		ToolCursorChar[OvalSelectionTool] := chr(89);
		ToolCursorChar[PickerTool] := chr(77);
		ToolCursorChar[AngleTool] := chr(89);
		ToolCursorChar[PointingTool] := chr(89);
		ToolTime := 0;
		LutTime := 0;
		StartOfLines := ToolRect[LastTool].bottom - 1;
		LinesTop := StartOfLines + 10;
		for i := 1 to nLineTypes do
			with lines[i] do
				begin
					left := LinesLeft;
					top := LinesTop;
					right := LinesRight;
					case i of
						1, 2, 3, 4: 
							bottom := top + i;
						5: 
							bottom := top + 6;
						6: 
							bottom := top + 8
					end;
					LinesTop := bottom + 4;
				end;
		LineWidth := 1;
		LineIndex := 1;
		with CheckRect do
			begin
				left := 0;
				top := StartOfLines;
				right := LinesLeft;
				bottom := theight;
			end;
	end;


	procedure AllocateBuffers;
		var
			tPort: GrafPtr;
			err: OSErr;
			BufSizeStr: str255;
			atemp: integer;
	begin
		GetPort(tPort);
		NumToString(BufferSize div 1024, BufSizeStr);
		BigBufSize := BufferSize * 2;
		if FreeMem > (BigBufSize + 300000) then
			BigBuf := NewPtr(BigBufSize)
		else
			BigBuf := nil;
		if BigBuf = nil then
			BigBufSize := 0;
		if BigBuf <> nil then
			UndoBuf := BigBuf
		else
			begin
				if FreeMem > (BufferSize + 200000) then
					UndoBuf := NewPtr(BufferSize)
				else
					UndoBuf := nil;
			end;
		if UndoBuf <> nil then
			UndoBufSize := BufferSize
		else
			begin
				PutMessage(concat('There is not enough memory available to allocate the ', BufSizeStr, 'K Undo buffer. Many operations may fail or be Undoable.'));
				UndoBufSize := 0;
			end;
		if BigBuf <> nil then
			ClipBuf := ptr(ord4(BigBuf) + BufferSize)
		else
			begin
				if FreeMem > (BufferSize + 300000) then
					ClipBuf := NewPtr(BufferSize)
				else
					ClipBuf := nil;
			end;
		if UndoBuf <> nil then
			begin
				UndoInfoRec := NoInfo^;
				UndoInfo := @UndoInfoRec;
				with UndoInfo^ do
					begin
						osroiRgn := NewRgn;
						PicBaseAddr := UndoBuf;
						new(osPort);
						OpenCPort(osPort);
						osPort^.portPixMap^^.BaseAddr := PicBaseAddr;
					end;
			end;
		if ClipBuf <> nil then
			begin
				ClipBufSize := BufferSize;
				ClipBufInfoRec := NoInfo^;
				ClipBufInfo := @ClipBufInfoRec;
				with ClipBufInfo^ do
					begin
						osroiRgn := NewRgn;
						PicBaseAddr := ClipBuf;
						new(osPort);
						OpenCPort(osPort);
						osPort^.portPixMap^^.BaseAddr := PicBaseAddr;
						BytesPerRow := 0;
					end;
			end
		else
			begin
				PutMessage(concat('There is not enough memory available to allocate the ', BufSizeStr, 'K Clipboard Buffer. Many operations, including Copy and Paste, may fail.'));
				ClipBufSize := 0;
			end;
		SetPort(tPort);
	end;


	procedure GetSettings;
		var
			Size, ticks: LongInt;
			ok: boolean;
			SettingsH: handle;
	begin
		SettingsH := GetResource('SETT', 1000);
		if (ResError = NoErr) and (SettingsH <> nil) then
			begin
				Size := GetHandleSize(SettingsH);
				if size = SizeOF(settings) then
					begin
						BlockMove(SettingsH^, @settings, size);
						with settings, info^ do
							begin
								ForegroundIndex := sForegroundIndex;
								BackgroundIndex := sBackgroundIndex;
								BrushHeight := sBrushHeight;
								BrushWidth := sBrushWidth;
								AirbrushDiameter := sAirbrushDiameter;
								AirbrushRadius := AirbrushDiameter div 2;
								AirbrushRadius2 := AirbrushRadius * AirbrushRadius;
								LUTMode := sLUTMode;
								ColorStart := sColorStart;
								ColorWidth := sColorWidth;
								CurrentFontID := sCurrentFontID;
								CurrentStyle := SCurrentStyle;
								CurrentSize := sCurrentSize;
								TextJust := sTextJust;
								TextBack := sTextBack;
								nExtraColors := sNExtraColors;
								ExtraColors := sExtraColors;
								InvertVideo := sInvertVideo;
								Measurements := sMeasurements;
								InvertPlots := sInvertPlots;
								AutoScalePlots := sAutoScalePlots;
								LinePlot := sLinePlot;
								DrawPlotLabels := sDrawPlotLabels;
								ProfilePlotMin := sProfilePlotMin;
								ProfilePlotMax := sProfilePlotMax;
								FixedSizePlot := sFixedSizePlot;
								ProfilePlotWidth := sProfilePlotWidth;
								ProfilePlotHeight := sProfilePlotHeight;
								FramesToAverage := sFramesToAverage;
								NewPicWidth := sNewPicWidth;
								NewPicHeight := sNewPicHeight;
								BufferSize := sBufferSize;
								MaxScionWidth := sMaxScionWidth;
								ThresholdToForeground := sThresholdToForeground;
								NonThresholdToBackground := sNonThresholdToBackground;
								VideoChannel := sVideoChannel;
								WhatToImport := sWhatToImport;
								ImportCustomWidth := sImportCustomWidth;
								ImportCustomHeight := sImportCustomHeight;
								ImportCustomOffset := sImportCustomOffset;
								WandAutoMeasure := sWandAutoMeasure;
								WandAutoNumber := sWandAutoNumber;
								BinaryIterations := sBinaryIterations;
								ScaleArithmetic := sScaleArithmetic;
								UseZeroForBlack := sUseZeroForBlack;
								InvertYCoordinates := sInvertYCoordinates;
								precision := sPrecision;
								MinParticleSize := sMinParticleSize;
								MaxParticleSize := sMaxParticleSize;
								IgnoreParticlesTouchingEdge := sIgnoreParticlesTouchingEdge;
								LabelParticles := sLabelParticles;
								OutlineParticles := sOutlineParticles;
{$IFC Arlo }
								FFTConfig := sFFTConfig;
								MaskConfig := sMaskConfig;
{$ENDC }
							end;
					end;
				case info^.LUTMode of
					PseudoColor32, custom, CustomGrayscale: 
						UpdateColors;
					AppleDefault: 
						ok := LoadCLUTResource(AppleDefaultCLUT);
					Spectrum: 
						Load256ColorCLUT;
				end;
				if nExtraColors > 0 then
					RedrawCLUTWindow;
				if UseZeroForBlack then
					InvertGrayLevels;
			end;
		ReleaseResource(SettingsH);
		UpdateTextMenu;
	end;


	procedure MakePatterns;
{Creates the patterns used to create the "marching ants". Thanks to}
{ Seth Snyder on CompuServe for the example.}
		var
			i, j: Integer;
	begin
		j := 0;
		for i := 0 to 7 do
			begin
				pat[i][(j + 0) mod 8] := $1F;
				pat[i][(j + 1) mod 8] := $3E;
				pat[i][(j + 2) mod 8] := $7C;
				pat[i][(j + 3) mod 8] := $F8;
				pat[i][(j + 4) mod 8] := $F1;
				pat[i][(j + 5) mod 8] := $E3;
				pat[i][(j + 6) mod 8] := $C7;
				pat[i][(j + 7) mod 8] := $8F;
				j := j + 1;
			end;
		PatIndex := 0;
	end;


	procedure InitExtraColors;
		var
			i, j, ctop, cbottom, entry: integer;
			tRect: rect;
	begin
		with ExtraColors[1] do
			begin
				red := -1;
				green := 0;
				blue := 0;
			end;
		with ExtraColors[2] do
			begin
				red := 0;
				green := -1;
				blue := 0;
			end;
		with ExtraColors[3] do
			begin
				red := 0;
				green := 0;
				blue := -1;
			end;
		with ExtraColors[4] do
			begin
				red := -1;
				green := -1;
				blue := 0;
			end;
		with ExtraColors[5] do
			begin
				red := 0;
				green := -1;
				blue := -1;
			end;
		with ExtraColors[6] do
			begin
				red := -1;
				green := 0;
				blue := -1;
			end;
		ctop := 256;
		cbottom := ctop + ExtraColorsHeight;
		for i := 1 to MaxExtraPlus2 do
			begin
				SetRect(tRect, 0, ctop, cwidth, cbottom);
				ExtraColorsRect[i] := tRect;
				ctop := ctop + ExtraColorsHeight;
				cbottom := cbottom + ExtraColorsHeight;
			end;
		ExtraColorsEntry[1] := WhiteIndex;
		ExtraColorsEntry[2] := BlackIndex;
		entry := FirstExtraColorsEntry;
		j := 3;
		for i := 1 to MaxExtraColors do
			begin
				ExtraColorsEntry[j] := entry;
				j := j + 1;
				Entry := Entry + 1;
			end;
	end;


	function GetSlotBase (id: integer): LongInt;
  {Returns the 24-bit slot base address of the NuBus card with the specified id.}
{   Returns 0 if a card with the given id is not found.}
		type
			SPRAMRecord = packed record
					BoardId: integer;
					VenderUse: packed array[1..6] of SignedByte;
				end;
		var
			SlotBlock: SpBlock;
			sparm: SPRAMRecord;
			SparmAddr: LongInt;
			i: integer;
			err: OSErr;
	begin
		with SlotBlock do
			begin
				SparmAddr := LongInt(@sparm);
				spResult := SparmAddr;
				for i := 9 to 15 do
					begin
						spSlot := i;
						err := sReadPRAMRec(@SlotBlock);
						if sparm.BoardID = id then
							begin
								GetSlotBase := spSlot * $100000;
								exit(GetSlotBase)
							end;
					end;
				GetSlotBase := 0;
			end;
	end;


	procedure SetupQCPort;
{Set up color graf port using the memory on the QuickCapture}
{board as the PixMap so we can use CopyBits .}
		var
			tPort: GrafPtr;
			trect: rect;
	begin
		GetPort(tPort);
		new(qcPort);
		OpenCPort(qcPort);
		SetRect(trect, 0, 0, qcwidth, qcheight);
		with qcPort^ do
			begin
				with PortPixMap^^ do
					begin
						BaseAddr := ptr(DTSlotBase);
						bounds := trect;
						RowBytes := BitOr(qcRowBytes, $8000);
					end;
				PortRect := trect;
				RectRgn(visRgn, trect);
			end;
		SetPort(tPort);
	end;


	procedure LookForFrameGrabbers;
		const
			ControlRegOffset = $80000;
			ChannelRegOffset = $80004;
			DT2255id = $11A;
			ScionID = $14B;
			PalBufferSize = 393216; {768 x 512}
		var
			err: OSErr;
			tPort: GrafPtr;
			SlotBase: LongInt;
	begin
		qcPort := nil;
		SlotBase := GetSlotBase(ScionID);
		if (SlotBase <> 0) and not OptionKeyDown then
			begin
				FrameGrabber := Scion;
				ScionSlotBase := SlotBase
			end
		else
			begin
				SlotBase := GetSlotBase(DT2255id);
				if SlotBase <> 0 then
					begin
						FrameGrabber := QuickCapture;
						DTSlotBase := SlotBase
					end
				else
					FrameGrabber := NoFrameGrabber
			end;
		qcWidth := 640;
		qcHeight := 480;
		if FrameGrabber = QuickCapture then
			begin
				ControlReg := ptr(DTSlotBase + ControlRegOffset);
				ChannelReg := ptr(DTSlotBase + ControlRegOffset + 4);
				if band(ChannelReg^, 8) = 8 then
					begin {Check for 50Hz(PAL) card}
						qcWidth := 768;
						qcHeight := 512;
						if BufferSize < PalBufferSize then
							BufferSize := PalBufferSize;
					end;
				SetupQCPort;
				ResetQuickCapture;
			end;
	end;


	procedure MakeTiffDirectory;
		var
			i: integer;
	begin
		with TiffInfo do
			begin
				with header do
					begin
						ByteOrder := 'MM';
						Version := 42;
						FirstIFDOffset := 8;
					end;
				nEntries := 7;
				for i := 1 to nEntries do
					with directory[i] do
						begin
							ftype := 3;
							length := 1
						end;
				with directory[1] do
					begin
						TagField := SubFileType;
						offset := bsl(1, 16);
					end;
				with directory[2] do
					begin
						TagField := ImageWidth;
						offset := 0;
					end;
				with directory[3] do
					begin
						TagField := ImageLength;
						offset := 0;
					end;
				with directory[4] do
					begin
						TagField := BitsPerSample;
						offset := bsl(8, 16);
					end;
				with directory[5] do
					begin
						TagField := PhotoInterp;
						offset := 0;
					end;
				with directory[6] do
					begin
						TagField := StripOffsets;
						ftype := 4;
						offset := TiffDirSize + HeaderSize;
					end;
				with directory[7] do
					begin
						TagField := ImageHdrTag;
						ftype := 4;
						offset := TiffDirSize;
					end;
				NextIFD := 0;
				for i := 1 to TiffFillerSize do
					filler[i] := 0;
			end;
	end;


	procedure CheckBits;
		const
			QD32Trap = $AB03;
			UnimplementedTrap = $A89F;
		var
			ColorQDExists: boolean;
			MainDevice: GDHandle;
			ScreenPixMap: PixMapHandle;
			myEnvRec: SysEnvRec;
			err: OSErr;
	begin
		err := SysEnvirons(1, myEnvRec);
		ColorQDExists := (err <> envNotPresent) and MyEnvRec.HasColorQD;
		if not ColorQDExists then
			begin
				PutMessage('Sorry, Image requires a Macintosh with Color QuickDraw.');
				ExitToShell;
			end;
		Has32BitQuickDraw := nGetTrapAddress(QD32Trap, ToolTrap) <> nGetTrapAddress(UnimplementedTrap, ToolTrap);
		MainDevice := GetMainDevice;
		if MainDevice^^.gdPmap^^.PixelSize <> 8 then
			begin
				PutMessage('Image requires 8-bit video. Use the Control Panel to switch to 256 color mode.');
				ExitToShell;
			end;
		ScreenPixMap := MainDevice^^.gdPMap;
		ScreenRowBytes := BitAnd(ScreenPixMap^^.rowBytes, $1fff);
		ScreenBase := ScreenPixMap^^.baseAddr;
	end;


	procedure SetupMenus;
		var
			i: integer;
	begin
		AppleMenuH := GetMenu(AppleMenu);
		InsertMenu(AppleMenuH, 0);
		FileMenuH := GetMenu(FileMenu);
		InsertMenu(FileMenuH, 0);
		EditMenuH := GetMenu(EditMenu);
		InsertMenu(EditMenuH, 0);
		OptionsMenuH := GetMenu(OptionsMenu);
		InsertMenu(OptionsMenuH, 0);
		EnhanceMenuH := GetMenu(EnhanceMenu);
		InsertMenu(EnhanceMenuH, 0);
		AnalyzemenuH := GetMenu(AnalyzeMenu);
		InsertMenu(AnalyzemenuH, 0);
{$IFC Arlo }
		FFTMenuH := GetMenu(FFTMenu);
		InsertMenu(FFTMenuH, 0);
{$ENDC }
		VideoMenuH := GetMenu(VideoMenu);
		InsertMenu(VideoMenuH, 0);
		TextMenuH := GetMenu(TextMenu);
		InsertMenu(TextMenuH, 0);
		WindowsMenuH := GetMenu(WindowsMenu);
		InsertMenu(WindowsMenuH, 0);

		FontMenuH := GetMenu(FontMenu);
		InsertMenu(FontMenuH, -1);
		SizeMenuH := GetMenu(SizeMenu);
		InsertMenu(SizeMenuH, -1);
		StyleMenuH := GetMenu(StyleMenu);
		InsertMenu(StyleMenuH, -1);
		BinaryMenuH := GetMenu(BinaryMenu);
		InsertMenu(BinaryMenuH, -1);
		ArithmeticMenuH := GetMenu(ArithmeticMenu);
		InsertMenu(ArithmeticMenuH, -1);
		SortPaletteMenuH := GetMenu(SortPaletteMenu);
		InsertMenu(SortPaletteMenuH, -1);
{$IFC Arlo }
		PSScalingMenuH := GetMenu(PSScalingMenu);
		InsertMenu(PSScalingMenuH, -1);
		NthRootMenuH := GetMenu(NthRootMenu);
		InsertMenu(NthRootMenuH, -1);
		AutoMenuH := GetMenu(AutoMenu);
		InsertMenu(AutoMenuH, -1);
{$ENDC }

		DrawMenuBar;
		AddResMenu(AppleMenuH, 'DRVR');
		AddResMenu(FontMenuH, 'FONT');
		NumFontItems := CountMItems(FontMenuH);
		SetMenuItem(VideoMenuH, SetVideoItem, FrameGrabber <> NoFrameGrabber);
	end;


	procedure FindMonitors;
{Generate a list of monitors so we can update the color tables of multiple monitors.}
{This wouldn't be necessary if we were using the Palette Manager.}
		var
			nextDevice: GDHandle;
	begin
		nMonitors := 0;
		nextDevice := GetDeviceList;
		while nextDevice <> nil do
			begin
				if TestDeviceAttribute(nextDevice, screenDevice) and TestDeviceAttribute(nextDevice, screenActive) then
					if nextDevice^^.gdPmap^^.PixelSize = 8 then
						begin
							nMonitors := nMonitors + 1;
							Monitors[nMonitors] := nextDevice;
						end;
				nextDevice := GetNextDevice(nextDevice);
			end; {while}
	end;


	procedure Init;
		var
			i: integer;
			p: SyspPtr;
			mbhp: ^integer;
	begin
		SetApplLimit(ptr(LongInt(GetApplLimit) - StackSize));
		MaxApplZone;
		InitGraf(@ThePort);
		InitFonts;
		InitWindows;
		InitCursor;
  {PLHeapInit(100000,5000,Nil,true,true)-Needed for MPW}
		TEInit;
		InitDialogs(@SysResume);
		CheckBits;
		FindMonitors;
		new(ScreenPort);
		OpenPort(ScreenPort);
		NoInfo := @NoInfoRec;
		Info := NoInfo;
		ResultsWindow := nil;
		with NoInfo^ do
			begin
				nlines := 0;
				PixelsPerLine := 0;
				PicSize := 0;
				PicBaseAddr := nil;
				osPort := nil;
				RoiShowing := false;
				RoiType := NoRoi;
				roiRect := SrcRect;
				osRoiRect := SrcRect;
				osroiRgn := NewRgn;
				title := 'NoInfo';
				Magnification := 1.0;
				PictureType := NullPicture;
				wptr := nil;
				Changes := false;
				BytesPerRow := 0;
				PixMapSize := 0;
				SetRect(SrcRect, 0, 0, 0, 0);
				PicRect := SrcRect;
				wrect := SrcRect;
				initwrect := wrect;
				savewrect := wrect;
				SaveSrcRect := SrcRect;
				SaveMagnification := magnification;
				savehloc := 0;
				savevloc := 0;
				ScaleToFitWindow := false;
				ColorStart := 30;
				ColorWidth := 8;
				LUTMode := GrayScale;
				units := '  ';
				FullUnits := 'Pixel';
				UnitsID := pixels;
				RawSpatialScale := 0.0;
				ScaleMagnification := 1.0;
				SpatialScale := RawSpatialScale * ScaleMagnification;
				PixelsPerCM := 0.0;
				UnitsPerCM := 0.0;
				UnitOfMeasure := '';
				PicNum := 1;
				HeaderOffset := -1;
				ImageDataOffset := -1;
				for i := 0 to 255 do
					ctable[i].value := 0;
				Fit := Poly3;
				Calibrated := false;
				nCoefficients := 0;
				for i := 1 to 6 do
					Coefficient[i] := 0.0;
				p1x := 0;
				p1y := 0;
				p2x := 255;
				p2y := 255;
				deltax := 255;
				deltay := 255;
				BinaryPic := false;
				WindowState := NormalWindow;
				FileDepth := EightBits;
{$IFC Arlo }
				FHTBuf := nil;
				FHTScale := 0;
{$ENDC }
			end;
		new(CScreenPort);
		OpenCPort(CScreenPort);
		finished := false;
		FlushEvents(EveryEvent, 0);
		for i := 1 to 10 do
			MoreMasters;
		mbhp := pointer(MBarHeight);
		MenuBarHeight := mbhp^;
		SetRect(trect, tleft, ttop, tleft + twidth, ttop + theight);
		ToolWindow := NewCWindow(nil, trect, 'Tools', true, NoGrowDocProc, nil, false, 0);
		WindowPeek(ToolWindow)^.WindowKind := ToolKind;
		BringToFront(ToolWindow);
		ScreenWidth := ScreenBits.Bounds.right;
		ScreenHeight := ScreenBits.Bounds.bottom;
		with BlackRGB do
			begin
				red := 0;
				blue := 0;
				green := 0;
			end;
		with WhiteRGB do
			begin
				red := -1;
				blue := -1;
				green := -1;
			end;
		ThresholdStart := 100;
		ThresholdEnd := 150;
		with ThresholdColor do
			begin
				red := -1;
				green := 0;
				blue := 0;
			end;
		Thresholding := false;
		nExtraColors := 0;
		GrayMapReady := false;
		ResetGrayMap;   {LUT must be setup before InitMenus}
		InitMenus;
		SetRect(gmrect, gmleft, gmtop, gmleft + gmwidth, gmtop + gmheight);
		SetRect(gmSlide1, gmrectleft, gmrectbottom + gmSlide1Offset, gmrectleft + gmSlideWidth, gmrectbottom + gmSlide1Offset + gmSlideHeight);
		gmSlide1i := gmSlide1;
		InsetRect(gmSlide1i, 1, 1);
		SetRect(gmSlide2, gmrectleft, gmrectbottom + gmSlide2Offset, gmrectleft + gmSlideWidth, gmrectbottom + gmSlide2Offset + gmSlideHeight);
		gmSlide2i := gmSlide2;
		gmFixedSlope := false;
		InsetRect(gmSlide2i, 1, 1);
		SetRect(gmIcon1, gmIcon1left, gmrectbottom + gmIconOffset, gmIcon1left + gmIconWidth, gmrectbottom + gmIconOffset + gmIconHeight);
		SetRect(gmIcon2, gmIcon2left, gmrectbottom + gmIconOffset, gmIcon2left + gmIconWidth, gmrectbottom + gmIconOffset + gmIconHeight);
		GrayMapWindow := NewWindow(nil, gmrect, ' Gray Map ', true, NoGrowDocProc, nil, false, 0);
		WindowPeek(GrayMapWindow)^.WindowKind := GrayMapKind;
		SetRect(GrayMapRect, gmRectLeft, gmRectTop, gmRectRight, gmRectBottom);
		GrayMapRect2 := GrayMapRect;
		InsetRect(GrayMapRect2, -2, -2);
		cheight := 256 + (2 + nExtraColors) * ExtraColorsHeight;
		SetRect(crect, cleft, ctop, cleft + cwidth, ctop + cheight);
		LUTWindow := NewCWindow(nil, crect, 'LUT', true, NoGrowDocProc, nil, false, 0);
		WindowPeek(LUTWindow)^.WindowKind := LUTKind;
		rleft := 2;
		if ScreenHeight > 480 then
			rtop := ScreenHeight - rheight - 5
		else
			rtop := 358;
		SetRect(trect, rleft, rtop, rleft + rwidth, rtop + rheight);
		ResultsWindow := NewWindow(nil, trect, 'Results', true, NoGrowDocProc, nil, false, 0);
		BringToFront(ResultsWindow);
		WindowPeek(ResultsWindow)^.WindowKind := ResultsKind;
		BuggyWatch := GetCursor(WatchCursor);
		InitTools;
		MakeCursors;
		nPics := 0;
		HistoWindow := nil;
		PlotWindow := nil;
		IsInsertionPoint := false;
		MaskRgn := NewRgn;
		PlotPICT := nil;
		AutoscalePlots := true;
		InvertPlots := false;
		LinePlot := true;
		DrawPlotLabels := true;
		FixedSizePlot := false;
		ProfilePlotMin := 0;
		ProfilePlotMax := 255;
		ProfilePlotWidth := 300;
		ProfilePlotHeight := 150;
		AirbrushDiameter := 32;
		AirbrushRadius := 16;
		AirbrushRadius2 := 256;
		BrushWidth := 10;
		BrushHeight := 10;
		CurrentUndoSize := 0;
		p := GetSyspPtr;
		BlinkTime := BitAnd($000F, p^.volclik) * 4;
		MakePatterns;
		InitColor('Default', 0);
		info^.LUTMode := GrayScale;
		PaletteName := '';
		PicLeftBase := twidth + cwidth + 10;
		PicTopBase := MenuBarHeight + 20;
		PicLeft := PicLeftBase;
		PicTop := PicTopBase;
		CurrentColorIndex := NoColor;
		CurrentFontID := Helvetica;
		CurrentStyle := []; {plain}
		CurrentSize := 24;
		TextJust := teJustLeft;
		TextBack := NoBack;
		MouseState := NotInRoi;
		WhatsOnClip := Nothing;
		PasteMode := NormalPaste;
		InitExtraColors;
		OldScrapCount := GetScrapCount;
		ClipboardConverted := false;
		with results do
			begin
				minCalibratedValue := -1;
				maxCalibratedValue := -1;
				x := 0;
				y := 0;
				Length := 0.0;
				angle := 0;
			end;
		BufferSize := DefaultBufferSize;
		LookForFrameGrabbers;
		VideoChannel := 0;
		Digitizing := false;
		debugging := false;
		BlankFieldInfo := nil;
		QuickCaptureInfo := nil;
		ScionInfo := nil;
		InvertVideo := false;
		PlotCount := 0;
		ClipTextInBuffer := false;
		TextBufP := TextBufPtr(NewPtr(SizeOf(TextBufType)));
		if TextBufP = nil then
			ExitToShell;
		MeasurementsP := MeasurementsPtr(NewPtr(SizeOf(MeasurementsType)));
		if MeasurementsP = nil then
			ExitToShell;
		nRegions := 0;
		nRegions2 := 0;
		UnsavedAreas := 0;
		nPoints := 0;
		UnsavedPoints := 0;
		nLengths := 0;
		nLengths2 := 0;
		UnsavedLengths := 0;
		lengths[0] := 0.0;
		with MeasurementsP^ do
			begin
				mean[0] := 0.0;
				sd[0] := 0.0;
				PixelCount[0] := 0;
				mode[0] := 0.0;
				IntegratedDensity[0] := 0.0;
				plength[0] := 0.0;
			end;
		for i := 1 to MaxStandards do
			StandardValues[i] := BadReal;
		nStandards := 0;
		for i := 0 to 255 do
			value[i] := i;
		WhatToUndo := NothingToUndo;
		WhatToCopy := NothingToCopy;
		PrintRecord := nil;
		printing := false;
		ShowingList := false;
		HalftoneFrequency := 50;
		HalftoneAngle := 45;
		HalftoneDotFunction := true;
		cr := chr(13);
		tab := chr(9);
		BackSpace := chr(8);
		measuring := false;
		measurements := [AreaM, MeanM];
		nMeasurements := 0;
		FramesToAverage := 16;
		PixelLength := 0.0;
		Copying := false;
		NewPicWidth := 552;
		NewPicHeight := 436;
		RestoreUndoBuf := true;
		MakeTiffDirectory;
		MaxScionWidth := 600;
		ThresholdToForeground := true;
		NonThresholdToBackground := true;
		SelectionMode := NewSelection;
		RoiMovementState := Unconstrained;
		PasteControl := nil;
		PasteTransferMode := SrcCopy;
		WhatToImport := ImportTIFF;
		ImportCustomWidth := 512;
		ImportCustomHeight := 512;
		ImportCustomOffset := 0;
		ImportCustomDepth := EightBits;
		ImportSwapBytes := false;
		ImportAll := false;
		RoiNudged := false;
		SetForegroundColor(BlackIndex);
		SetBackgroundColor(WhiteIndex);
		for i := 0 to MaxPixelsPerLine - 1 do
			BlankLine[i] := WhiteIndex;
		SavingOutline := false;
		RestoringOutline := false;
		OpPending := false;
		RedoSelection := false;
		WandAutoMeasure := false;
		WandAutoNumber := false;
		OptionKeyWasDown := false;
		BinaryIterations := 1;
		ScaleArithmetic := true;
		ResultsMessage := '';
		SaveAsWhat := asTIFF;
		FitEllipse := (xyLocM in measurements) or (MajorAxisM in measurements) or (MinorAxisM in measurements) or (AngleM in measurements);
		AnalyzingParticles := false;
		RedirectSampling := false;
		MinParticleSize := 1;
		MaxParticleSize := 999999;
		LabelParticles := true;
		OutlineParticles := false;
		IgnoreParticlesTouchingEdge := false;
		SaveAllFlag := NoSaveAll;
		InvertYCoordinates := true;
		ContinuousHistogram := false;
		DrawLabels(' ', '', '');
		HistogramThresholdStart := 0;
		HistogramThresholdEnd := 255;
		RoiUpdateTime := 0;
		precision := 2;
		MeasurementToRedo := 0;
{$IFC Arlo }
		InFrequencyDomain := false;
		InitMaskNFFT;
		FFTNumber := 1;
		InverseFFTNumber := 1;
{$ENDC }
	end;


end.