unit Camera;
{ Routines used by the Image program for supporting video digitizers. 						}
{ Video digitizers are supported through the Video Digitizer Manager (VDM)	}
{ which is an object library linked with this program.  The VDM calls 						}
{ Video Definition Functions (VDEFs) to do all the real work.  The VDEFs 				}
{ are developed separately and copied into the resource file for the 								}
{ application as executable code-type resources (rsrc name is 'VDEF'). 				}

{ The VDM/VDEF functionality is defined in a document originated by							}
{ MicroFrontier, Inc and extended by Perceptics Corporation.  Contact						}
{ Perceptics for questions about this document or the software package.					}

{ The VDM/VDEF functionality was designed around three video cards							}
{ available for the Macintosh II.  These are:																												}
{		¥  Perceptics PixelTools series,																																			}
{		¥  Data Translation QuickCapture,																																	}
{		¥  Scion Image Capture 2.																																								}
{ Other video digitizers may be used with Image just by writing a VDEF					}
{ for that board and copying the resulting 'VDEF' resource (plus any other			}
{ resources, eg, DLOGs, used by the VDEF itself) into the Image application		}
{ resource fork or into the Image.rsrc file before linking.																}


interface


	uses
		QuickDraw, Palettes, Printing, Slots, StandardFile, Memory, Devices, {}
		Resources, SegLoad, Lists, Fonts, Files, Folders, {}
		VDigitizerDefs, VDigitizerM, Globals, Utilities, Graphics, File2, {}
		Text, File1, DialogSupport, Analysis;


	procedure GetVDSettings;
	procedure SaveVDSettings;
	procedure AdjustDigitizeRect (grabRect: Rect);
	function Ave1ItemDlog (DlogNum: integer): boolean;
	function IntegrationDlog (DlogNum: integer): boolean;
	procedure CheckVdFuncs;
	function CustomALUDlog: Boolean;
	function GeoWeightDlog (DlogNum: integer): boolean;
	function GetLiveHistogram (hSkip, vSkip: Integer): OSErr;
	procedure GetNewBkgImage;
	function GetVDPixel (lh, lv: Integer): Integer;
	function GrabRectToClipBuf: OSErr;
	function IntegDlog: Boolean;
	procedure LookForFrameGrabbers;
	procedure MaintainDigitizing;
	function VDReadLUT (var theLut: VDLutRec): OSErr;
	function SetupCaptureWindow: boolean;
	procedure SetVideoChannel (newChannel: Integer);
	procedure StartDigitizing;
	procedure CaptureFrameOffscreen;
	procedure StopDigitizing;
	function StartContinuousHistogram: Boolean;
	procedure HighlightPixels;
	procedure LoadInputLookupTable;
	procedure LoadOutputLookupTable;
	procedure AdjustDisplayRect (var theDisplayRect: rect);
	procedure RefreshVideoControl;
	procedure ShowVideoControl;
	procedure DoVideoControl (item: integer);
	procedure CaptureAndDisplayFrame;
	function AllocateAccumBuffer: boolean;
	procedure ShowTriggerMessage;
	procedure SelectCameraWindow;


implementation


	const
		NoBoardID = 0;

{	procedure MyBug;
	inline
		$a9ff;}

	procedure ShowTriggerMessage;
	var
		CurrentVDigitizer: VDHandle;
	begin
		CurrentVDigitizer := GetActiveVDigitizer;
		if ExternalTrigger and (CurrentVDigitizer <> nil) then
			ShowMessage(concat('EXTERNAL TRIGGER MODE', crStr, '(Press mouse button to exit)'));
	end;


	procedure SelectCameraWindow;
  {If there is a Camera window, activate it, otherwise, do nothing.}
		var
			i: integer;
			TempInfo: InfoPtr;
	begin
		for i := 1 to nPics do begin
				TempInfo := pointer(WindowPeek(PicWindow[i])^.RefCon);
				if TempInfo^.PictureType = VDigitizerType then begin
						if PicWindow[i] <> nil then begin
								if OpPending then
									KillRoi;
								SelectWindow(PicWindow[i]);
								Info := TempInfo;
								ActivateWindow;
							end; {if}
						leave;
					end; {if}
			end; {for}
	end;


	function IOCheck (err: OSerr): integer;
		var
			ignore: integer;
			errStr: str255;
	begin
		if err <> noErr then begin
				NumToString(err, errStr);
				ParamText('', errStr, '', '');
				InitCursor;
				ignore := alert(IOErrorID, nil);
			end;
		IOCheck := err;
	end;


{-- procedure LookForFrameGrabbers - Initializes the video digitizers and related structures.	}
	procedure LookForFrameGrabbers;
		var
			status: OSErr;
			tPort: GrafPtr;
			VDigFrameSize: Point;
			VDigImageSize: Point;
	begin
		InitVDigitizers;
		if ActvVDigitizer <> nil then begin
				status := GetVDigitizerVideoSize(nil, VDigImageSize);
				status := GetVDigitizerFBSize(nil, 1, VDigFrameSize);
				if status = noErr then begin
						vdSWidth := VDigFrameSize.h;
						vdSHeight := VDigFrameSize.v;
						vdCWidth := VDigImageSize.h;
						vdCHeight := VDigImageSize.v;
					end
				else begin
						vdSWidth := 600;
						vdSHeight := 480;
						vdCWidth := 600;
						vdCHeight := 480;
					end;
				GetVDSettings;
			end
		else begin
				vdSWidth := 0;
				vdSHeight := 0;
				vdCWidth := 0;
				vdCHeight := 0;
			end;
	end;


	function VDOpenTextFile (var name: str255; var RefNum: integer): boolean;
		var
			where: Point;
			typeList: SFTypeList;
			reply: SFReply;
			err: OSErr;
			pBlock: WDPBRec;
	begin
		where.v := 120;
		where.h := 120;
		typeList[0] := 'TEXT';
		SFGetFile(Where, '', nil, 1, @typeList, nil, reply);
		if reply.good then
			with reply do begin
					name := fname;
					RefNum := vRefNum;
					VDOpenTextFile := true;
				end
		else
			VDOpenTextFile := false;
	end;



{	VDReadLUT		}

{	This routine reads a lookup table from a selected tabular								}
{	text file. Each LUT file contains two columns separated by a tab.		}
{	Each row is delimited by a return. Each row contains the								}
{	intensity to map and the mapped value corresponding to it. Only		}
{	the intensity values contained in the file are mapped, other						}
{	"missing" intensities are mapped to 0 (black). Only 8-bit LUTs		}
{	are supported, although the length can be an arbitrary size.					}

	function VDReadLUT (var theLut: VDLutRec): OSErr;

		type
			bigLutType = packed array[0..2047] of UnsignedByte;
			bigLutPtrType = ^bigLutType;
		var
			lclError: OSErr;
			lclTypeList: SFTypeList;
			lclWhere: point;
			lclFRefNum: integer;
			inFileName, rdBfr, strBfr: Str255;
			status: integer;
			lutNum, lutValue: longint;
			lclLutPtr: bigLutPtrType;
			x,y: LongReal;

	begin
	{ Initialize the completion status. }
		lclError := noErr;

	{ Get the name of the file to load the LUT.  If it opens successfully then ... }
		if (VDOpenTextFile(inFileName, lclFRefNum) = true) then begin

				{  Initialize the input record and let the user know it may be a while	}
				InitTextInput(inFileName, lclFRefNum);

				{  Check to see if memory is available to store the LUT  }
				if theLut.custom = nil then
					theLut.custom := NewPtr(theLut.size + 1);

				if theLut.custom <> nil then begin

						lclLutPtr := bigLutPtrType(theLut.custom);

						{  Make sure the LUT identifier is at the beginning of the file		}
						status := CopyLineFromText(rdBfr);
						strBfr := 'LUT';
						if (IUMagIDString(@rdBfr[1], @strBfr[1], 3, 3) = 0) then begin

								{  Initialize the LUT data so that missing intensities will be	}
								{  mapped to zero (black) rather than contain garbage.			}
								for lutNum := 0 to theLut.size do
									lclLutPtr^[lutNum] := UnsignedByte(37);

								{  Get the LUT data and put it into the custom LUT block		}
								while (not TextEof) do begin
										x := GetNumber;
										if x <> NoValue then begin
											y := GetNumber;
											if y <> NoValue then begin
												lutNum := trunc(x);
												lutValue := trunc(y);
												{ReadString(rdBfr, lutNum, lutValue); ** ReadString not in MW Pascal! }
												if (lutNum >= 0) and (lutNum <= theLut.size) then
													lclLutPtr^[lutNum] := UnsignedByte(lutValue);
											end;
										end;

									end;				{ while (not TextEof) }

							end;						{ if (IUMagIDString(@rdBfr[1], @strBfr[1], 3, 3) = 0) }

					end							{ if VDInputLUT[SelLUT].custom <> nil }
				else
					PutMessage('There is not enough memory available to load this LUT table. ');

				{  Restore the cursor  }
				InitCursor;

			end;

	{ Return the completion status. }
		VDReadLut := lclError;

	end;


	procedure HighlightPixels;
		var
			lut: MyCSpecArray;
	begin
		with info^ do begin
				lut := ctable;
				MinRGB := lut[1].rgb;
				lut[1].rgb := Highlight1;
				MaxRGB := lut[254].rgb;
				lut[254].rgb := Highlight254;
				LoadLUT(lut);
			end;
	end;


	procedure UnHighlightPixels;
		var
			lut: MyCSpecArray;
	begin
		with info^ do begin
				lut := ctable;
				lut[1].rgb := MinRGB;
				lut[254].rgb := MaxRGB;
				LoadLUT(lut);
			end;
	end;



{-- procedure SetVideoChannel - Selects the specified video input 		}
{-- channel on the selected digitizer to use for video input.								}

	procedure SetVideoChannel;  { (newChannel:Integer); }
		var
			VDigHandle: VDHandle;
			status: OSErr;
			nChannels: Integer;
	begin

		VDigHandle := GetActiveVDigitizer;
		if VDigHandle <> nil then begin
				{ Set the specified input channel as the new camera source channel. }
				status := GetVDigitizerNumChannels(nil, nChannels);
				if (newChannel > 0) and (newChannel <= nChannels) then
					status := SetVDigitizerSrc(newChannel);
			end;

	end;


	function GetSlotID (slot: Integer): Integer;
	{ Returns the ID number of the card in the specified slot or	}
	{ zero if no card is installed in that slot.					}
		var
			mySpBlock: SpBlockPtr;	{ Our slot parameter block	}
			ID: Integer;					{ The card's ID			}

	begin
	{ Allocate a Slot Parameter Block for communicating with the Slot Manager. }
		ID := 0;
		mySpBlock := SpBlockPtr(NewPtr(sizeof(SpBlock)));
		if (mySpBlock = nil) then begin
				PutMessage('Out of memory');
				Exit(GetSlotID);
			end;

	{ Get a pointer to the card's slot resource list.	}
		mySpBlock^.spSlot := slot;
		mySpBlock^.spID := sRsrc_Type;
		mySpBlock^.spExtDev := 0;

		if (SRsrcInfo(mySpBlock) = noErr) then begin		{ ... and get the card's ID.	}
				mySpBlock^.spID := BoardId;
				if (SReadWord(mySpBlock) = noErr) then
					ID := mySpBlock^.spResult
				else
					ID := 0;
			end
		else
			ID := 0;

	{ We're finished with the Slot Parameter Block.	}
		DisposePtr(Ptr(mySpBlock));

	{ Return the card's ID.	}
		GetSlotID := ID;

	end;	{ End of GetSlotID	}


	function GetMaxDMAWidth: integer;
		var
			gDevHandle: GDHandle;
			dCEHandle: AuxDCEHandle;
			NUBSInfoH: NUBSInfoHandle;
			NUBSInfoP: NUBSInfoPtr;
			vDevId: integer;
			p: ptr;
			i: integer;
	begin
		gDevHandle := GetMainDevice;
		dCEHandle := AuxDCEHandle(GetDCtlEntry(gDevHandle^^.gdRefNum));

{ Find the Id in the NUBS resource}
		vDevID := GetSlotId(dCEHandle^^.dCtlSlot);
		NUBSInfoH := NUBSInfoHandle(GetResource('NUBS', 0));
		if (ResError <> noErr) then begin
	{ Return 0 if video device not set up in NUBS Resource.	}
				GetMaxDMAWidth := 0;
			end
		else begin
				HNoPurge(Handle(NUBSInfoH));
				vdevNUBSInfo.vdevID := 0;
				GetMaxDMAWidth := 0;

				NUBSInfoP := NUBSInfoH^;
				while (NUBSInfoP^.vdevID <> 0) and (vdevNUBSInfo.vdevID = 0) do begin
						if (NUBSInfoP^.vdevID = vDevID) then begin
								GetMaxDMAWidth := NUBSInfoP^.vdevMaxWidth;
								Exit(GetMaxDMAWidth);
							end;
						NUBSInfoP := NUBSInfoPtr(ord4(NUBSInfoP) + SizeOf(NUBSInfoRec));
					end;

			end;
	end;


	function AllocateAccumBuffer: boolean;
		var
			status: OSErr;
			bufferSize, temp: LongInt;
			VDigImageSize: Point;
			depth, offset, bitsToShift: Integer;
	begin

			{ Set the size for the digitizer's current camera. }
		status := GetVDigitizerVideoSize(nil, VDigImageSize);
		status := GetVDigitizerCameraPixelInfo(depth, offset, bitsToShift);
		if status <> noErr then
			depth := 1
		else
			depth := (depth + 7) div 8;
		temp := longInt(VDigImageSize.h) * longInt(VDigImageSize.v) * depth * 2;

			{ See if there is already a buffer allocated.  }
		if gBigFBPtr <> nil then begin

					{ A buffer already exists.  Is it big enough? }
				bufferSize := GetPtrSize(gBigFBPtr);
				if bufferSize >= temp then begin
						AllocateAccumBuffer := true;
						exit(AllocateAccumBuffer);
					end;

					{ The current buffer is not big enough.  Get rid of it and allocate a new one. }
				DisposePtr(gBigFBPtr);
			end;

		gBigFBPtr := NewPtr(temp);
		if gBigFBPtr = nil then begin
				AllocateAccumBuffer := false;
				PutMessage('Not enough memory available for this digitizer.  Try increasing the Application Memory Size.');
			end  {if gBigFBPtr = nil}
		else
			AllocateAccumBuffer := true;

	end;


	procedure GetVDGlobalSettings;
		var
			err, status: OSErr;
			f, i: integer;
			ByteCount: LongInt;
			ok: boolean;
			size, temp: LongInt;
			theMPListHdl: VDMPListHdl;
			theMPSize: longInt;
			VDigHandle, CurrentVDigitizer: VDHandle;
			theID: integer;
			VDigFrameSize: Point;
			VDigImageSize: Point;
			done, doesAvg, hasALU, hasCtrl: boolean;
			edgesRect: Rect;
			cameraSize: Point;
			SettingsFileOK: boolean;
			index, cameraType: integer;
	begin

		with vdGlobalSettings do begin

				status := GetVDigitizerID(theID);
				if (status <> noErr) or (theID = NoBoardID) then
					vdDigitizerID := NoBoardID
				else
					vdDigitizerID := theID;
				HighlightSaturatedPixels := vdHighlightSaturatedPixels;
				OscillatingMovies := vdOscillatingMovies;
				BlindMovieCapture := vdBlindMovies;
				UseDMADisplay := vdBoardSettings[vdBoardIndex].vdUseDMADisplay = 1;
				MaxDMADigWidth := vdBoardSettings[vdBoardIndex].vdMaxDMADigWidth;
				gExtTrigger := vdBoardSettings[vdBoardIndex].vdExternalTrigger;
				gIntegrationScalingType := IntegrationScalingType(vdBoardSettings[vdBoardIndex].vdIntegrationScalingType);
				gIntegrationMin := vdBoardSettings[vdBoardIndex].vdIntegrationMin;
				gIntegrationMax := vdBoardSettings[vdBoardIndex].vdIntegrationMax;

				if (vdBoardSettings[vdBoardIndex].vdInputLutNo < 1) or (vdBoardSettings[vdBoardIndex].vdInputLutNo > 10) then
					vdBoardSettings[vdBoardIndex].vdInputLutNo := 1;
				VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].kind := vdBoardSettings[vdBoardIndex].vdInputLUTRec.kind;
				VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].size := vdBoardSettings[vdBoardIndex].vdInputLUTRec.size;
				VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].range := vdBoardSettings[vdBoardIndex].vdInputLUTRec.range;
				VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].threshold := vdBoardSettings[vdBoardIndex].vdInputLUTRec.threshold;
				VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].brightness := vdBoardSettings[vdBoardIndex].vdInputLUTRec.brightness;
				VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].contrast := vdBoardSettings[vdBoardIndex].vdInputLUTRec.contrast;
				SelLUT := vdBoardSettings[vdBoardIndex].vdSelLUT;
				status := SetVDigitizerInLUT(SelLUT);
				LoadInputLookupTable;

					{ Set the Use DMA for Display control bit based on user selection }
				if UseDMADisplay then begin
						status := SetVDigitizerControlBits(0);
					end
				else begin
						status := SetVDigitizerControlBits(vdFcBDMAOut);
					end;


					{ Set the selected input channel as the new camera source channel. }
				status := SetVDigitizerSrc(vdBoardSettings[vdBoardIndex].vdInputChannel);

				VDOutputLut.kind := vdBoardSettings[vdBoardIndex].vdOutputLUTRec.kind;
				VDOutputLut.size := vdBoardSettings[vdBoardIndex].vdOutputLUTRec.size;
				VDOutputLut.range := vdBoardSettings[vdBoardIndex].vdOutputLUTRec.range;
				VDOutputLut.threshold := vdBoardSettings[vdBoardIndex].vdOutputLUTRec.threshold;
				VDOutputLut.brightness := vdBoardSettings[vdBoardIndex].vdOutputLUTRec.brightness;
				VDOutputLut.contrast := vdBoardSettings[vdBoardIndex].vdOutputLUTRec.contrast;
				status := SetVDigitizerOutLUT(vdBoardSettings[vdBoardIndex].vdOutputLUTNo);
				LoadOutputLookupTable;

				if vdBoardSettings[vdBoardIndex].vdNumModeParams <> 0 then begin
						theMPSize := sizeof(VDModalParamsList);
						theMPListHdl := VDMPListHdl(NewHandle(sizeof(VDModalParamsList)));
						status := GetVDigitizerModalParams(theMPListHdl);
						if vdBoardSettings[vdBoardIndex].vdNumModeParams = 1 then begin
								theMPListHdl^^.vdModalParams[1].vdMPIEntryValue := vdBoardSettings[vdBoardIndex].vdModeParams[1];
								status := SetVDigitizerModalParams(theMPListHdl);
							end
						else begin
								theMPListHdl^^.vdModalParams[0].vdMPIEntryValue := vdBoardSettings[vdBoardIndex].vdModeParams[1];
								theMPListHdl^^.vdModalParams[1].vdMPIEntryValue := vdBoardSettings[vdBoardIndex].vdModeParams[2];
								theMPListHdl^^.vdModalParams[2].vdMPIEntryValue := vdBoardSettings[vdBoardIndex].vdModeParams[3];
								theMPListHdl^^.vdModalParams[3].vdMPFEntryValue := vdBoardSettings[vdBoardIndex].vdShutterValue;
								status := SetVDigitizerModalParams(theMPListHdl);
							end;
						DisposeHandle(handle(theMPListHdl));
					end
				else
					status := SetVDigitizerMode(vdBoardSettings[vdBoardIndex].vdModeParams[1]);

				status := TestVDigitizerFeature(nil, vdFeBProgGain, hasCtrl);
				if hasCtrl then begin
						status := SetVDigitizerGain(vdBoardSettings[vdBoardIndex].vdGain);
						if (status <> noErr) then begin
								beep;
								exit(GetVDGlobalSettings);
							end;
					end;

				status := TestVDigitizerFeature(nil, vdFeBProgOffset, hasCtrl);
				if hasCtrl then begin
						status := SetVDigitizerOffset(vdBoardSettings[vdBoardIndex].vdOffset);
						if (status <> noErr) then begin
								beep;
								exit(GetVDGlobalSettings);
							end;
					end;

			{ Set the size parameters for the camera window based on digitizer parameters. }
				status := GetVDigitizerVideoSize(nil, VDigImageSize);
				status := GetVDigitizerDisplaySize(nil, VDigFrameSize);
				if status = noErr then begin
						vdSWidth := VDigImageSize.h;
						vdSHeight := VDigImageSize.v;
						vdCWidth := VDigFrameSize.h;
						vdCHeight := VDigFrameSize.v;
					end
				else begin
						vdSWidth := 600;
						vdSHeight := 480;
						vdCWidth := 600;
						vdCHeight := 480;
					end;

				status := TestVDigitizerFeature(nil, vdFeBDMAOut, hasCtrl);
				if hasCtrl then begin
						status := TestVDigitizerControl(nil, vdFcBDMAOut, hasCtrl);
						if hasCtrl then begin
								if (UseDMADisplay) then
									if (vdCWidth > MaxDMADigWidth) then
										vdCWidth := MaxDMADigWidth;
							end
						else begin
								if (vdCWidth > MaxDMADigWidth) then
									vdCWidth := MaxDMADigWidth;
							end;
					end;

{					{ Dispose of any buffers if they exist  }
{    if gBigFBPtr <> nil then}
{    disposPtr(gBigFBPtr);}

{				{  Check to see if buffers need to be allocated  }
{    status := TestVDigitizerFunction(nil, vdFuBArithAvg, doesAvg);}
{    status := TestVDigitizerFeature(nil, vdFeBALU, hasALU);}
{    if doesAvg and not hasALU then begin}

{						{find out the sizes and allocate a huge buffer}
{    MyBug;}
{    temp := longInt(VDigImageSize.h) * longInt(VDigImageSize.v) * 2;}
{    gBigFBPtr := NewPtr(temp);}
{    if gBigFBPtr = nil then begin}
{    done := false;}
{    PutMessage('Not enough memory available for this digitizer.  Try increasing the Application Memory Size.');}
{    end;  {if gBigFBPtr = nil}
{    end;  {if doesAvg and not hasALU}

				{ Set the camera parameters for the DCI board. }
				cameraType := vdBoardSettings[vdBoardIndex].vdCameraSelection;
				status := SetVDigitizerCamera(cameraType);
				SetPt(cameraSize, vdBoardSettings[vdBoardIndex].vdCameraWidth[cameraType], vdBoardSettings[vdBoardIndex].vdCameraHeight[cameraType]);
				status := SetVDigitizerCameraSize(cameraSize);
				SetRect(edgesRect, vdBoardSettings[vdBoardIndex].vdCameraLeftEdge[cameraType], vdBoardSettings[vdBoardIndex].vdCameraTopEdge[cameraType], vdBoardSettings[vdBoardIndex].vdCameraRightEdge[cameraType], vdBoardSettings[vdBoardIndex].vdCameraBottomEdge[cameraType]);
				status := SetVDigitizerCameraEdges(edgesRect);
				status := SetVDigitizerCameraName(vdBoardSettings[vdBoardIndex].vdCameraName[cameraType]);
				status := SetVDigitizerCameraLineTime(vdBoardSettings[vdBoardIndex].vdCameraLineTime[cameraType]);
				status := SetVDigitizerCameraPixelInfo(vdBoardSettings[vdBoardIndex].vdCameraDepth[cameraType], vdBoardSettings[vdBoardIndex].vdCameraPixelOffset[cameraType], vdBoardSettings[vdBoardIndex].vdCameraBitsToShift[cameraType]);
				status := SetVDigitizerCameraSpecialInfo(vdBoardSettings[vdBoardIndex].vdCameraSpecialInfo[cameraType]);
				gvdCameraSelection := cameraType;
				gvdCameraWidth := vdBoardSettings[vdBoardIndex].vdCameraWidth[cameraType];
				gvdCameraHeight := vdBoardSettings[vdBoardIndex].vdCameraHeight[cameraType];
				gvdCameraLeftEdge := vdBoardSettings[vdBoardIndex].vdCameraLeftEdge[cameraType];
				gvdCameraTopEdge := vdBoardSettings[vdBoardIndex].vdCameraTopEdge[cameraType];
				gvdCameraRightEdge := vdBoardSettings[vdBoardIndex].vdCameraRightEdge[cameraType];
				gvdCameraBottomEdge := vdBoardSettings[vdBoardIndex].vdCameraBottomEdge[cameraType];
				gvdCameraName := vdBoardSettings[vdBoardIndex].vdCameraName[cameraType];
				gvdCameraLineTime := vdBoardSettings[vdBoardIndex].vdCameraLineTime[cameraType];
				gvdCameraDepth := vdBoardSettings[vdBoardIndex].vdCameraDepth[cameraType];
				gvdCameraPixelOffset := vdBoardSettings[vdBoardIndex].vdCameraPixelOffset[cameraType];
				gvdCameraBitsToShift := vdBoardSettings[vdBoardIndex].vdCameraBitsToShift[cameraType];
				gvdCameraSpecialInfo := vdBoardSettings[vdBoardIndex].vdCameraSpecialInfo[cameraType];

				gVDSetupDone := true;
				gVideoProcChoice := iRawSample;
				gvdOperation := vdNone;

			end;
	end;


	procedure GetVDSettings;
		var
			err, status: OSErr;
			f, i: integer;
			ByteCount: LongInt;
			ok: boolean;
			size, temp: LongInt;
			theMPListHdl: VDMPListHdl;
			theMPSize: longInt;
			VDigHandle, CurrentVDigitizer: VDHandle;
			theID: integer;
			VDigFrameSize: Point;
			VDigImageSize: Point;
			done, doesAvg, hasALU, hasCtrl: boolean;
			edgesRect: Rect;
			cameraSize: Point;
			needToInitPrefsFile, SettingsFileOK: boolean;
			index: integer;
			PrefsFound:boolean;
			PrefsVRef: integer;
			PrefsDirID: LongInt;
			PrefsSpec: FSSpec;
	begin
		PrefsFound:=false;
		if System7 then begin
			{Look in the Preferences folder}
			err:=FindFolder(kOnSystemDisk, kPreferencesFolderType,
						kDontCreateFolder, PrefsVRef, PrefsDirID);
			if err=noErr then
				err:=FSMakeFSSpec(PrefsVRef, PrefsDirID, VDPrefsName, PrefsSpec);
			if err=noErr then
				err:=FSpOpenDF(PrefsSpec, fsCurPerm, f);
			if err=noErr then
				PrefsFound:=true;
		end;
		if not PrefsFound then begin
			{Look in the System folder}
			err := fsopen(VDPrefsName, SystemRefNum, f);
		end;
		
		needToInitPrefsFile := false;
		if err = NoErr then begin
				err := GetEof(f, ByteCount);
				if ByteCount > SizeOf(vdGlobalSettings) then
					ByteCount := SizeOf(vdGlobalSettings);
				err := fsRead(f, ByteCount, @vdGlobalSettings);
				if err <> NoErr then
					exit(GetVDSettings);
				err := fsClose(f);
				with vdGlobalSettings do begin
						if vdID <> 'IMAG' then begin
								PutMessage('The Image Prefs file in the System Folder is corrupted. Please delete it and try again.');
								ExitToShell;
							end;

						SettingsFileOK := true;
{$IFC PowerPC}
						if vdMVersion <> '158P' then begin
								PutMessage('The VD Image Prefs file in the System Folder is wrong. A new one will be created.');
								SettingsFileOK := false;
								needToInitPrefsFile := true;
							end;
{$ELSEC}
						if vdMVersion <> '1586' then begin
								PutMessage('The VD Image Prefs file in the System Folder is wrong. A new one will be created.');
								SettingsFileOK := false;
								needToInitPrefsFile := true;
							end;
{$ENDC}

						if (SettingsFileOK) then begin
							{ Check if same digitizers are present as are stored in settings. }
							for index := 1 to MaxVDigs do begin
									VDigHandle := GetNthVDigitizer(index - 1);
									if (VDigHandle <> nil) then begin
											HLock(Handle(VDigHandle));
											status := SetVDigitizer(VDigHandle);
											status := GetVDigitizerID(theID);
											if (theID <> vdBoardSettings[index].vdBoardID) then begin
													SettingsFileOK := false;
												end;
											HUnlock(Handle(VDigHandle));
										end;
								end;  { end for index }
	
							if (not SettingsFileOK) then begin
									PutMessage('The digitizer settings file is invalid. Please use Video Control to initialize digitizer settings.');
									needToInitPrefsFile := true;
								end;
						 end;

						if (SettingsFileOK) then begin
							{ Check that floating point settings are reasonable. }
							for index := 1 to MaxVDigs do begin
									if (vdBoardSettings[index].vdGain < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdGain > 10000.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOffset < -1000.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOffset > 1000.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdInputLUTRec.threshold < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdInputLUTRec.threshold > 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdInputLUTRec.brightness < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdInputLUTRec.brightness > 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdInputLUTRec.contrast < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdInputLUTRec.contrast > 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOutputLUTRec.threshold < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOutputLUTRec.threshold > 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOutputLUTRec.brightness < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOutputLUTRec.brightness > 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOutputLUTRec.contrast < 0.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdOutputLUTRec.contrast > 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdShutterValue < 1.0) then  SettingsFileOK := false;
									if (vdBoardSettings[index].vdShutterValue > 100000.0) then  SettingsFileOK := false;
								end;
								
							if (not SettingsFileOK) then begin
									PutMessage('Some digitizer settings are invalid. Please use Video Control to initialize digitizer settings.');
									needToInitPrefsFile := true;
								end;
						 end;
				
						if not needToInitPrefsFile then begin
								VDigHandle := GetFirstVDigitizer;
								CurrentVDigitizer := nil;
								while (VDigHandle <> nil) and (CurrentVDigitizer = nil) do begin
										HLock(Handle(VDigHandle));
										status := SetVDigitizer(VDigHandle);
										status := GetVDigitizerID(theID);
										if (theID = vdDigitizerID) then
											CurrentVDigitizer := VDigHandle
										else begin
												HUnlock(Handle(VDigHandle));
												VDigHandle := GetNextVDigitizer;
											end;  { if theID = vdDigitizerID }
									end;  { while VDigHandle <> nil }

								if (CurrentVDigitizer = nil) then begin
										PutMessage('The digitizer specified in preferences is invalid. Please use Video Control to initialize digitizer settings.');
										needToInitPrefsFile := true;
									end;
							end;
					end;
			end
		else		{No settings file exists, so build a default one. }
			begin
				needToInitPrefsFile := true;
			end;

		if needToInitPrefsFile then begin
				with vdGlobalSettings do begin
						VDigHandle := GetFirstVDigitizer;
						CurrentVDigitizer := nil;
						if (VDigHandle <> nil) then begin
								HLock(Handle(VDigHandle));
								status := SetVDigitizer(VDigHandle);
								CurrentVDigitizer := VDigHandle;
								HUnlock(Handle(VDigHandle));
							end;  { if VDigHandle <> nil }

						if CurrentVDigitizer = nil then begin
								Exit(GetVDSettings);
							end
						else begin
								vdID := 'IMAG';
								status := GetVDigitizerID(theID);
								vdDigitizerID := theID;
{$IFC PowerPC}
								vdMVersion := '158P';
{$ELSEC}
								vdMVersion := '1586';
{$ENDC}
								vdHighlightSaturatedPixels := false;
								vdOscillatingMovies := false;
								vdBlindMovies := false;
								vdBoardIndex := 1;
								for index := 1 to MaxVDigs do begin
										VDigHandle := GetNthVDigitizer(index - 1);
										if (VDigHandle <> nil) then begin
												HLock(Handle(VDigHandle));
												status := SetVDigitizer(VDigHandle);
												status := GetVDigitizerID(theID);
												HUnlock(Handle(VDigHandle));
											end
										else begin
												theID := NoBoardID;
											end;

										vdBoardSettings[index].vdBoardID := theID;
										vdBoardSettings[index].vdUseDMADisplay := 0;
										vdBoardSettings[index].vdMaxDMADigWidth := GetMaxDMAWidth;
										vdBoardSettings[index].vdGain := 1.0;
										vdBoardSettings[index].vdOffset := 0.0;
										vdBoardSettings[index].vdInputLUTNo := 1;
										vdBoardSettings[index].vdOutputLUTNo := 1;
										vdBoardSettings[index].vdInputLUTRec.kind := rLLNormal;
										vdBoardSettings[index].vdInputLUTRec.size := 256;
										vdBoardSettings[index].vdInputLUTRec.range := 256;
										vdBoardSettings[index].vdInputLUTRec.threshold := 0.5;
										vdBoardSettings[index].vdInputLUTRec.brightness := 0.5;
										vdBoardSettings[index].vdInputLUTRec.contrast := 0.5;
										vdBoardSettings[index].vdSelLUT := 1;
										vdBoardSettings[index].vdInputChannel := 1;
										vdBoardSettings[index].vdOutputLUTRec.kind := rLLNormal;
										vdBoardSettings[index].vdOutputLUTRec.size := 256;
										vdBoardSettings[index].vdOutputLUTRec.range := 256;
										vdBoardSettings[index].vdOutputLUTRec.threshold := 0.5;
										vdBoardSettings[index].vdOutputLUTRec.brightness := 0.5;
										vdBoardSettings[index].vdOutputLUTRec.contrast := 0.5;
										for i := 0 to NumModeParams do
											vdBoardSettings[index].vdModeParams[i] := 0;
										vdBoardSettings[index].vdShutterValue := 100.0;
										vdBoardSettings[index].vdNumModeParams := 0;
										vdBoardSettings[index].vdExternalTrigger := vdSource;
										vdBoardSettings[index].vdIntegrationScalingType := ord(IntegScaleNone);
										vdBoardSettings[index].vdIntegrationMin := 0;
										vdBoardSettings[index].vdIntegrationMax := 65536;
										vdBoardSettings[index].vdCameraSelection := 0;
										vdBoardSettings[index].vdCameraWidth[0] := 1364;
										vdBoardSettings[index].vdCameraHeight[0] := 1035;
										vdBoardSettings[index].vdCameraTopEdge[0] := 4;
										vdBoardSettings[index].vdCameraLeftEdge[0] := 28;
										vdBoardSettings[index].vdCameraBottomEdge[0] := 4;
										vdBoardSettings[index].vdCameraRightEdge[0] := 16;
										vdBoardSettings[index].vdCameraName[0] := 'DCI-MegaPlus 1.4';
										vdBoardSettings[index].vdCameraLineTime[0] := 135;
										vdBoardSettings[index].vdCameraDepth[0] := 8;
										vdBoardSettings[index].vdCameraPixelOffset[0] := 0;
										vdBoardSettings[index].vdCameraBitsToShift[0] := 0;
										vdBoardSettings[index].vdCameraSpecialInfo[0] := 0;
										vdBoardSettings[index].vdCameraWidth[1] := 2032;
										vdBoardSettings[index].vdCameraHeight[1] := 2028;
										vdBoardSettings[index].vdCameraTopEdge[1] := 0;
										vdBoardSettings[index].vdCameraLeftEdge[1] := 4;
										vdBoardSettings[index].vdCameraBottomEdge[1] := 0;
										vdBoardSettings[index].vdCameraRightEdge[1] := 8;
										vdBoardSettings[index].vdCameraName[1] := 'DCI-MegaPlus 4.2';
										vdBoardSettings[index].vdCameraLineTime[1] := 237;
										vdBoardSettings[index].vdCameraDepth[1] := 8;
										vdBoardSettings[index].vdCameraPixelOffset[1] := 0;
										vdBoardSettings[index].vdCameraBitsToShift[1] := 0;
										vdBoardSettings[index].vdCameraSpecialInfo[1] := 0;
										vdBoardSettings[index].vdCameraWidth[2] := 1536;
										vdBoardSettings[index].vdCameraHeight[2] := 1032;
										vdBoardSettings[index].vdCameraTopEdge[2] := 4;
										vdBoardSettings[index].vdCameraLeftEdge[2] := 0;
										vdBoardSettings[index].vdCameraBottomEdge[2] := 4;
										vdBoardSettings[index].vdCameraRightEdge[2] := 4;
										vdBoardSettings[index].vdCameraName[2] := 'DCI-MegaPlus 1.6';
										vdBoardSettings[index].vdCameraLineTime[2] := 177;
										vdBoardSettings[index].vdCameraDepth[2] := 10;
										vdBoardSettings[index].vdCameraPixelOffset[2] := 0;
										vdBoardSettings[index].vdCameraBitsToShift[2] := 8;
										vdBoardSettings[index].vdCameraSpecialInfo[2] := 0;
										vdBoardSettings[index].vdCameraWidth[3] := 1364;
										vdBoardSettings[index].vdCameraHeight[3] := 1035;
										vdBoardSettings[index].vdCameraTopEdge[3] := 4;
										vdBoardSettings[index].vdCameraLeftEdge[3] := 28;
										vdBoardSettings[index].vdCameraBottomEdge[3] := 4;
										vdBoardSettings[index].vdCameraRightEdge[3] := 16;
										vdBoardSettings[index].vdCameraName[3] := 'DCI-Other';
										vdBoardSettings[index].vdCameraLineTime[3] := 94;
										vdBoardSettings[index].vdCameraDepth[3] := 8;
										vdBoardSettings[index].vdCameraPixelOffset[3] := 0;
										vdBoardSettings[index].vdCameraBitsToShift[3] := 0;
										vdBoardSettings[index].vdCameraSpecialInfo[3] := 0;
									end;
							end;
						VDigHandle := GetFirstVDigitizer;
						status := SetVDigitizer(VDigHandle);
					end;
			end;

		GetVDGlobalSettings;

	end;


	procedure SaveVDSettings;
		var
			TheInfo: FInfo;
			ByteCount: LongInt;
			f, i: integer;
			err, status: OSErr;
			theMPListHdl: VDMPListHdl;
			theMPSize: longInt;
			VDigHandle, CurrentVDigitizer: VDHandle;
			hasCtrl: boolean;
			cameraSize: Point;
			edgesRect: Rect;
			cameraType: integer;
			PrefsError: boolean;
			PrefsVRef: integer;
			PrefsDirID: LongInt;
			PrefsSpec: FSSpec;
	begin
		CurrentVDigitizer := GetActiveVDigitizer;
		if CurrentVDigitizer <> nil then begin
				with vdGlobalSettings do begin
						vdID := 'IMAG';
						status := GetVDigitizerID(vdDigitizerID);

						vdOscillatingMovies := OscillatingMovies;
						vdBlindMovies := BlindMovieCapture;
						vdHighlightSaturatedPixels := HighlightSaturatedPixels;
						vdBoardSettings[vdBoardIndex].vdBoardID := vdDigitizerID;
						if UseDMADisplay then
						  vdBoardSettings[vdBoardIndex].vdUseDMADisplay := 1
						else
						  vdBoardSettings[vdBoardIndex].vdUseDMADisplay := 0;
						vdBoardSettings[vdBoardIndex].vdMaxDMADigWidth := GetMaxDMAWidth;
						vdBoardSettings[vdBoardIndex].vdExternalTrigger := gExtTrigger;
						vdBoardSettings[vdBoardIndex].vdIntegrationScalingType := ord(gIntegrationScalingType);
						vdBoardSettings[vdBoardIndex].vdIntegrationMin := gIntegrationMin;
						vdBoardSettings[vdBoardIndex].vdIntegrationMax := gIntegrationMax;

						status := TestVDigitizerFeature(nil, vdFeBProgGain, hasCtrl);
						if hasCtrl then begin
								status := GetVDigitizerGain(vdBoardSettings[vdBoardIndex].vdGain);
								if (status <> noErr) then begin
										beep;
										PutMessage('Error reading gain on  digitizer.');
										exit(SaveVDSettings);
									end;
							end;

						status := TestVDigitizerFeature(nil, vdFeBProgOffset, hasCtrl);
						if hasCtrl then begin
								status := GetVDigitizerOffset(vdBoardSettings[vdBoardIndex].vdOffset);
								if (status <> noErr) then begin
										beep;
										PutMessage('Error reading offset on  digitizer.');
										exit(SaveVDSettings);
									end;
							end;

						status := GetVDigitizerSrc(vdBoardSettings[vdBoardIndex].vdInputChannel);
						if (status <> noErr) then begin
								beep;
								PutMessage('Error reading input channel.');
								exit(SaveVDSettings);
							end;

						status := GetVDigitizerOutLUT(vdBoardSettings[vdBoardIndex].vdOutputLutNo);
						vdBoardSettings[vdBoardIndex].vdOutputLUTRec.kind := VDOutputLut.kind;
						vdBoardSettings[vdBoardIndex].vdOutputLUTRec.size := VDOutputLut.size;
						vdBoardSettings[vdBoardIndex].vdOutputLUTRec.range := VDOutputLut.range;
						vdBoardSettings[vdBoardIndex].vdOutputLUTRec.threshold := VDOutputLut.threshold;
						vdBoardSettings[vdBoardIndex].vdOutputLUTRec.brightness := VDOutputLut.brightness;
						vdBoardSettings[vdBoardIndex].vdOutputLUTRec.contrast := VDOutputLut.contrast;

						status := GetVDigitizerInLUT(vdBoardSettings[vdBoardIndex].vdInputLutNo);
						if (vdBoardSettings[vdBoardIndex].vdInputLutNo < 1) or (vdBoardSettings[vdBoardIndex].vdInputLutNo > 10) then
							vdBoardSettings[vdBoardIndex].vdInputLutNo := 1;
						vdBoardSettings[vdBoardIndex].vdInputLUTRec.kind := VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].kind;
						vdBoardSettings[vdBoardIndex].vdInputLUTRec.size := VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].size;
						vdBoardSettings[vdBoardIndex].vdInputLUTRec.range := VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].range;
						vdBoardSettings[vdBoardIndex].vdInputLUTRec.threshold := VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].threshold;
						vdBoardSettings[vdBoardIndex].vdInputLUTRec.brightness := VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].brightness;
						vdBoardSettings[vdBoardIndex].vdInputLUTRec.contrast := VDInputLut[vdBoardSettings[vdBoardIndex].vdInputLutNo].contrast;
						vdBoardSettings[vdBoardIndex].vdSelLUT := SelLUT;

						if CurrentVDigitizer^^.vdModeInfo.vdMPListHdl <> nil then begin
								vdBoardSettings[vdBoardIndex].vdNumModeParams := 2;
								theMPSize := sizeof(VDModalParamsList);
								theMPListHdl := VDMPListHdl(NewHandle(sizeof(VDModalParamsList)));
								status := GetVDigitizerModalParams(theMPListHdl);
								if CurrentVDigitizer^^.vdModeInfo.vdMPListHdl^^.vdMPNParams = 1 then begin
										vdBoardSettings[vdBoardIndex].vdNumModeParams := 1;
										vdBoardSettings[vdBoardIndex].vdModeParams[0] := theMPListHdl^^.vdModalParams[1].vdMPIEntryValue;
									end
								else begin
										vdBoardSettings[vdBoardIndex].vdNumModeParams := 2;
										vdBoardSettings[vdBoardIndex].vdModeParams[1] := theMPListHdl^^.vdModalParams[0].vdMPIEntryValue;
										vdBoardSettings[vdBoardIndex].vdModeParams[2] := theMPListHdl^^.vdModalParams[1].vdMPIEntryValue;
										vdBoardSettings[vdBoardIndex].vdModeParams[3] := theMPListHdl^^.vdModalParams[2].vdMPIEntryValue;
										vdBoardSettings[vdBoardIndex].vdShutterValue := theMPListHdl^^.vdModalParams[3].vdMPFEntryValue;
									end;
								DisposeHandle(handle(theMPListHdl));
							end
						else begin
								vdBoardSettings[vdBoardIndex].vdNumModeParams := 0;
								status := GetVDigitizerMode(vdBoardSettings[vdBoardIndex].vdModeParams[1]);
							end;

						{ Get the current camera parameters for the DCI board. }
						status := GetVDigitizerCamera(vdBoardSettings[vdBoardIndex].vdCameraSelection);
						cameraType := vdBoardSettings[vdBoardIndex].vdCameraSelection;
						status := GetVDigitizerCameraSize(cameraSize);
						if status = noErr then begin
								vdBoardSettings[vdBoardIndex].vdCameraWidth[cameraType] := cameraSize.h;
								vdBoardSettings[vdBoardIndex].vdCameraHeight[cameraType] := cameraSize.v;
							end
						else begin
								vdBoardSettings[vdBoardIndex].vdCameraWidth[cameraType] := 0;
								vdBoardSettings[vdBoardIndex].vdCameraHeight[cameraType] := 0;
							end;
						status := GetVDigitizerCameraEdges(edgesRect);
						if status = noErr then begin
								vdBoardSettings[vdBoardIndex].vdCameraLeftEdge[cameraType] := edgesRect.left;
								vdBoardSettings[vdBoardIndex].vdCameraTopEdge[cameraType] := edgesRect.top;
								vdBoardSettings[vdBoardIndex].vdCameraRightEdge[cameraType] := edgesRect.right;
								vdBoardSettings[vdBoardIndex].vdCameraBottomEdge[cameraType] := edgesRect.bottom;
							end
						else begin
								vdBoardSettings[vdBoardIndex].vdCameraLeftEdge[cameraType] := 0;
								vdBoardSettings[vdBoardIndex].vdCameraTopEdge[cameraType] := 0;
								vdBoardSettings[vdBoardIndex].vdCameraRightEdge[cameraType] := 0;
								vdBoardSettings[vdBoardIndex].vdCameraBottomEdge[cameraType] := 0;
							end;
						status := GetVDigitizerCameraName(vdBoardSettings[vdBoardIndex].vdCameraName[cameraType]);
						status := GetVDigitizerCameraLineTime(vdBoardSettings[vdBoardIndex].vdCameraLineTime[cameraType]);
						status := GetVDigitizerCameraPixelInfo(vdBoardSettings[vdBoardIndex].vdCameraDepth[cameraType], vdBoardSettings[vdBoardIndex].vdCameraPixelOffset[cameraType], vdBoardSettings[vdBoardIndex].vdCameraBitsToShift[cameraType]);
						status := GetVDigitizerCameraSpecialInfo(vdBoardSettings[vdBoardIndex].vdCameraSpecialInfo[cameraType]);

					end; {with}

				if System7 then begin
					{Save in Preferences folder}
					PrefsError:=true;
					err:=FindFolder(kOnSystemDisk, kPreferencesFolderType,
								kDontCreateFolder, PrefsVRef, PrefsDirID);
					if err=noErr then
						err:=FSMakeFSSpec(PrefsVRef, PrefsDirID, VDPrefsName, PrefsSpec);
					if err=noErr then
						err:=FSpDelete(PrefsSpec);
					if (err=noErr) or (err=fnfErr) then begin
						err:=FSpCreate(PrefsSpec, 'Imag', 'PREF', smSystemScript);
						if err=noErr then
							err:=FSpOpenDF(PrefsSpec, fsCurPerm, f);
						if err=noErr then
							PrefsError:=false;
					end;
					if PrefsError then begin
						PutError('Error saving settings file');
						exit(SaveVDSettings);
					end;
				end else begin
					err := GetFInfo(VDPrefsName, SystemRefNum, TheInfo);
					if err = FNFerr then begin
						err := create(VDPrefsName, SystemRefNum, 'Imag', 'PREF');
						if IOCheck(err) <> 0 then begin
								PutMessage('Can not create preferences file.');
								exit(SaveVDSettings);
							end;
					 end;
					err := fsopen(VDPrefsName, SystemRefNum, f);
				end;
				if IOCheck(err) <> 0 then begin
						PutMessage('Can not open preferences file.');
						exit(SaveVDSettings);
					end;
				err := SetFPos(f, FSFromStart, 0);
				ByteCount := SizeOf(vdGlobalSettings);
				err := fswrite(f, ByteCount, @vdGlobalSettings);
				if IOCheck(err) <> 0 then begin
						err := fsclose(f);
						PutMessage('Error Writing to preferences file.');
						exit(SaveVDSettings)
					end;
				err := SetEof(f, ByteCount);
				err := fsclose(f);
				err := FlushVol(nil, SystemRefNum);
			end;
	end;


	procedure FillandLoadLut (whichLut: VDLutRec; LutNum: integer; doInput: boolean);
		type
			bigLutType = packed array[0..2047] of UnsignedByte;
			bigLutPtrType = ^bigLutType;
		const
			HalfPi = 1.570796327;
		var
			LUTHandle: LTabHandle;
			NumLutEntries, i: integer;
			neededSize: Size;
			LutValue, breakPt: integer;
			slope, bias: LongReal;
			status: OSErr;
			lclLutPtr: bigLutPtrType;

	begin
		{ Allocate a LUT buffer and fill it with data. }
		if doInput then
			status := GetVDigitizerInLUTSize(nil, LutNum, NumLutEntries)
		else
			status := GetVDigitizerOutLUTSize(nil, LutNum, NumLutEntries);

		neededSize := SizeOf(LUTTable) + NumLutEntries * SizeOf(LUTEntry);
		LUTHandle := LTabHandle(NewHandle(neededSize));
		HLock(Handle(LUTHandle));

		{  Invert  LUT		}
		InvertVideo := false;
		if whichLut.kind = rLLInverse then begin
				InvertVideo := true;
				for i := 0 to NumLutEntries - 1 do begin
						LUTHandle^^.ltTable[i].index := i;
						LUTHandle^^.ltTable[i].value := (NumLutEntries - 1) - i;
					end;
				LUTHandle^^.ltTable[0].value := LUTHandle^^.ltTable[1].value;
				LUTHandle^^.ltTable[NumLutEntries - 1].value := LUTHandle^^.ltTable[NumLutEntries - 2].value;
			end

		{  Normal  LUT		}
		else if whichLut.kind = rLLNormal then begin
				for i := 0 to NumLutEntries - 1 do begin
						LUTHandle^^.ltTable[i].index := i;
						LUTHandle^^.ltTable[i].value := i;
					end;
				LUTHandle^^.ltTable[0].value := LUTHandle^^.ltTable[1].value;
				LUTHandle^^.ltTable[NumLutEntries - 1].value := LUTHandle^^.ltTable[NumLutEntries - 2].value;
			end

		{  Custom  LUT		}
		else if whichLut.kind = rLLCustom then begin
				lclLutPtr := bigLutPtrType(whichLut.custom);
				for i := 0 to NumLutEntries - 1 do begin
						LUTHandle^^.ltTable[i].index := i;
						LUTHandle^^.ltTable[i].value := integer(lclLutPtr^[i]);
					end;
				LUTHandle^^.ltTable[0].value := LUTHandle^^.ltTable[1].value;
				LUTHandle^^.ltTable[NumLutEntries - 1].value := LUTHandle^^.ltTable[NumLutEntries - 2].value;
			end

		{  Threshold  LUT		}
		else if whichLut.kind = rLLThreshold then begin
				breakPt := integer(round((NumLutEntries - 2) * whichLut.threshold));
				for i := 0 to NumLutEntries - 1 do begin
						LUTHandle^^.ltTable[i].index := i;
						if i <= breakPt then
							LUTHandle^^.ltTable[i].value := 0
						else
							LUTHandle^^.ltTable[i].value := 254;
					end;
				LUTHandle^^.ltTable[0].value := LUTHandle^^.ltTable[1].value;
				LUTHandle^^.ltTable[NumLutEntries - 1].value := LUTHandle^^.ltTable[NumLutEntries - 2].value;
			end

		{  Brightness and Contrast LUT	 Adjustment		}
		else if whichLut.kind = rLLBrtCont then begin
				slope := sin(whichLut.contrast * HalfPi) / cos(whichLut.contrast * HalfPi);  { No tan fcn in MW Pascal!}
				bias := (LongReal(whichLut.range / 2.0 + 0.5)) - (LongReal(whichLut.range * (1.0 - whichLut.brightness) * slope));

				for i := 0 to NumLutEntries - 1 do begin
						LUTHandle^^.ltTable[i].index := i;
						LutValue := i mod (whichLut.range + 1);
						LutValue := trunc(LutValue * slope) + trunc(bias);
						if LutValue < 0 then
							LutValue := 0
						else if LutValue > whichLut.range then
							LutValue := whichLut.range;
						LUTHandle^^.ltTable[i].value := LutValue;
					end;
				LUTHandle^^.ltTable[0].value := LUTHandle^^.ltTable[1].value;
				LUTHandle^^.ltTable[NumLutEntries - 1].value := LUTHandle^^.ltTable[NumLutEntries - 2].value;
			end;
		LUTHandle^^.ltSize := NumLutEntries;


				{ Load the Lookup Table into the digitizer LUT. }
		if doInput then begin
				status := WriteVDigitizerInLUT(LutNum, vdLUT, Handle(LUTHandle));
				status := ReadVDigitizerInLUT(LutNum, i, Handle(LUTHandle));
			end
		else
			status := WriteVDigitizerOutLUT(LutNum, vdLUT, Handle(LUTHandle));
		HUnlock(Handle(LUTHandle));
		DisposeHandle(Handle(LUTHandle));
	end;  {procedure FillandLoadLut}


	procedure LoadInputLookupTable;
		var
			nInLUTs, CurrentLUT, Size, NumLutEntries, i: integer;
			status: OSErr;
			CurrentVDigitizer: VDHandle;
	begin
		CurrentVDigitizer := GetActiveVDigitizer;
		if CurrentVDigitizer <> nil then begin
				status := GetVDigitizerNumInLUTs(nil, nInLUTs);
				if nInLUTs > 0 then begin
						status := GetVDigitizerInLUT(CurrentLUT);
						if (CurrentLUT < 1) or (CurrentLUT > 10) then
							CurrentLUT := 1;
						if status = noErr then begin
								status := GetVDigitizerInLUTSize(nil, CurrentLUT, NumLutEntries);
								if NumLutEntries > 2 then
									FillandLoadLut(VDInputLut[SelLUT], CurrentLUT, true);
							end;
					end;
			end;
	end;


	procedure LoadOutputLookupTable;
		var
			nOutLUTs, CurrentLUT, NumLutEntries: integer;
			status: OSErr;
			CurrentVDigitizer: VDHandle;
	begin
		CurrentVDigitizer := GetActiveVDigitizer;
		if CurrentVDigitizer <> nil then begin
				status := GetVDigitizerNumOutLUTs(nil, nOutLUTs);
				if nOutLUTs > 0 then begin
						status := GetVDigitizerOutLUT(CurrentLUT);
						if status = noErr then begin
								status := GetVDigitizerOutLUTSize(nil, CurrentLUT, NumLutEntries);
								if NumLutEntries > 2 then
									FillandLoadLut(VDOutputLut, CurrentLUT, false);
							end;
					end;
			end;
	end;


		{  Display 0, 1 or theValue in a dialog field and hide the items as needed  }
	procedure DispSelField (theDialog: DialogPtr; maxValue, theValue, statItemNo, editItemNo: Integer);
		var
			theStr: Str255;
	begin
		if maxValue = 0 then begin
					{  Hide both items  }
				HideDialogItem(theDialog, statItemNo);
				HideDialogItem(theDialog, editItemNo);
			end  {  if maxValue = 0  }
		else if maxValue = 1 then begin
					{  Hide the editText item  }
				HideDialogItem(theDialog, editItemNo);
				ShowDialogItem(theDialog, statItemNo);
			end  {  if maxValue = 1  }
		else if maxValue > 1 then begin
					{  Hide the staticText item and select the editText field  }
				HideDialogItem(theDialog, statItemNo);
				ShowDialogItem(theDialog, editItemNo);
				SetDNum(theDialog, editItemNo, LongInt(theValue));
				SelectDialogItemText(theDialog, editItemNo, 0, gMaxInt);
			end
		else if maxValue = -1 then begin
					{  Hide the editText item and update the staticText field  }
				HideDialogItem(theDialog, editItemNo);
				ShowDialogItem(theDialog, statItemNo);
				SetDNum(theDialog, statItemNo, LongInt(theValue));
			end;
	end;


{  DoLoadLUTDlog--	}
{  function to get the desired LUT	information	}

	procedure DoLoadLUTDlog;
		const
			rLoadLUTDlog = 11200;
			rLLDlogLabel = 3;
			rLLCustom = 8;
			rLLThreshLabel = 9;
			rLLBrtLabel = 10;
			rLLContLabel = 11;
			rLLLdLUTLabel = 12;
			rLLLoadLUT = 13;
			rLLIMValue1 = 14;
			rLLIMLow1 = 15;
			rLLIMSlider1 = 16;
			rLLIMHi1 = 17;
			rLLIMValue2 = 18;
			rLLIMLow2 = 19;
			rLLIMSlider2 = 20;
			rLLIMHi2 = 21;
			rLLLutNumStatID = 27;
			rLLLutNumEditID = 28;
			rLLNumLUTsID = 29;

		var
			done, okay: boolean;
			oldPort: GrafPtr;
			LLDlog: DialogPtr;
			imSlider1, imSlider2: SliderInfo;
			lutType, oldLutType: integer;
			threshold, brightness, contrast: LongReal;
			choice, item, itemType: integer;
			itemHandle: handle;
			itemRect: Rect;
			update: boolean;
			itemText: Str255;
			error: OSErr;
			nLUTs, CurrentLUT, temp: integer;
			CurrentVDigitizer: VDHandle;
			myEventFilterProc: ModalFilterUPP;

	begin

		lutType := rLLNormal;
		oldLutType := 0;

		{  Initialize the completion status		}
		okay := false;
		done := false;

		{  Get info on the current digitizer and its LUTs				}
		CurrentVDigitizer := GetActiveVDigitizer;
		error := GetVDigitizerNumInLUTs(nil, nLUTs);
		if nLUTs < 1 then
			exit(DoLoadLUTDlog);
		HLock(Handle(CurrentVDigitizer));
		error := GetVDigitizerInLUT(CurrentLUT);
		if (CurrentLUT < 1) or (CurrentLUT > 10) then
			CurrentLUT := 1;

		{  Get the current operation parameters.		}
		lutType := VDInputLut[CurrentLUT].kind;
		threshold := VDInputLut[CurrentLUT].threshold;
		brightness := VDInputLut[CurrentLUT].brightness;
		contrast := VDInputLut[CurrentLUT].contrast;

		{  Save the current Grafport.		}
		GetPort(oldPort);

    {  Get the dialog.   }
		LLDlog := DSGetNewDialog(rLoadLUTDlog, nil, pointer(-1));
		SetPort(LLDlog);

		
		{  For PPC:  Get a routine descriptor for our dialog event filter proc so we can
			 call it in a mixed mode environment. }
		myEventFilterProc := NewModalFilterProc(@DSEventFilter);


   {  Initialize the dialog items.     }
		DSSetSliderInfo(imSlider1, LLDlog, rLLIMSlider1, 1, 100, 8, @DSSliderToText, rLLIMValue1, 0.0, 1.0, 1.0);
		DSSetSliderInfo(imSlider2, LLDlog, rLLIMSlider2, 1, 100, 8, @DSSliderToText, rLLIMValue2, 0.0, 1.0, 1.0);
		SetDString(LLDlog, rLLDlogLabel, 'Load Input LUT');
		DispSelField(LLDlog, nLUTs, CurrentLUT, rLLLutNumStatID, rLLLutNumEditID);

	{ Loop to process user inputs for the dialog. }
		repeat

			{  Select the dialog's grafport.		}
			SetPort(LLDlog);

			{  Get the current dialog values.  }
			if (oldLutType = rLLThreshold) then begin
					threshold := GetDReal(LLDlog, rLLIMValue1);
				end
			else if (oldLutType = rLLBrtCont) then begin
					brightness := GetDReal(LLDlog, rLLIMValue1);
					contrast := GetDReal(LLDlog, rLLIMValue2);
				end;

			{  Update the Intensity Mapping items. }
			{  Disable all of the items and enable only the ones we want  }
			if (lutType <> oldLutType) then begin

					{  Update the mode selection items		}
					if (OldLutTYpe <> 0) then
						DSSetIRadio(LLDlog, oldLutType, false);
					DSSetIRadio(LLDlog, lutType, true);

					{  Hide all of the mode specific items		}
					for item := rLLThreshLabel to rLLIMHi2 do
						HideDialogItem(LLDlog, item);

					{  Initialize and show the items applicable for the new mode		}
					case lutType of
						rLLThreshold:  begin
								itemText := StringOf(threshold : 5 : 3);
								SetDString(LLDlog, rLLIMValue1, itemText);
								DSTextToSlider(LLDlog, imSlider1.theSlider, rLLIMValue1);
								ShowDialogItem(LLDlog, rLLThreshLabel);
								for item := rLLIMValue1 to rLLIMHi1 do
									ShowDialogItem(LLDlog, item);
								DSTextToSlider(LLDlog, imSlider1.theSlider, rLLIMValue1);
							end;

						rLLBrtCont:  begin
								itemText := StringOf(brightness : 5 : 3);
								SetDString(LLDlog, rLLIMValue1, itemText);
								DSTextToSlider(LLDlog, imSlider1.theSlider, rLLIMValue1);

								itemText := StringOf(contrast : 5 : 3);
								SetDString(LLDlog, rLLIMValue2, itemText);
								DSTextToSlider(LLDlog, imSlider2.theSlider, rLLIMValue2);

								ShowDialogItem(LLDlog, rLLBrtLabel);
								ShowDialogItem(LLDlog, rLLContLabel);
								for item := rLLIMValue1 to rLLIMHi2 do
									ShowDialogItem(LLDlog, item);
								DSTextToSlider(LLDlog, imSlider1.theSlider, rLLIMValue1);
								DSTextToSlider(LLDlog, imSlider2.theSlider, rLLIMValue2);
							end;

						rLLCustom:  begin
								ShowDialogItem(LLDlog, rLLLdLUTLabel);
								ShowDialogItem(LLDlog, rLLLoadLUT);
							end;

					end;

					oldLutType := lutType;

				end;

			{  Display the dialog. }
			ShowWindow(LLDlog);

			OutlineButton(LLDlog, ok, 16);
			ModalDialog(myEventFilterProc, choice);

			if (choice = ok) then begin
					{  Set the status flag for an exit		}
					okay := true;
					done := true;
					item := 0;

				{ Check the LUT number to make sure it is valid. }
					temp := GetDNum(LLDlog, rLLLutNumEditID);
					if (temp > 0) and (temp <= nLUTs) then begin
							CurrentLUT := temp;
						end
					else
						okay := false;

				{ Check the parameters. If any are invalid then clear the done flag. }
					if (lutType = rLLThreshold) then begin
							if (threshold < 0.0) or (threshold > 1.0) then begin
									if (okay = true) then begin
											okay := false;
											item := rLLIMValue1;
										end;
								end;
						end
					else if (lutType = rLLBrtCont) then begin
							if (brightness < 0.0) or (brightness > 1.0) then begin
									if (okay = true) then begin
											okay := false;
											item := rLLIMValue1;
										end;
								end;
							if (contrast < 0.0) or (contrast > 1.0) then begin
									if (okay = true) then begin
											okay := false;
											item := rLLIMValue2;
										end;
								end;
						end;

							{ If an invalid e was detected then report the error and continue with the dialog. }
					if (okay = false) then begin
							if (item <> 0) then
								SelectDialogItemText(LLDlog, item, 0, gMaxInt);
							SysBeep(2);
							done := false;
						end;
				end;

			if (choice = cancel) then begin
					okay := false;
					done := true;
				end;

			if (choice = rLLIMValue1) or (choice = rLLIMValue2) then begin
					GetDialogItem(LLDlog, choice + 2, itemType, itemHandle, itemRect);
					DSTextToSlider(LLDlog, ControlHandle(itemHandle), choice);
				end;

			if (choice = rLLIMSlider1) or (choice = rLLIMSlider2) then begin
					GetDialogItem(LLDlog, choice, itemType, itemHandle, itemRect);
					DSSliderToText(LLDlog, ControlHandle(itemHandle), GetControlValue(ControlHandle(itemHandle)), choice - 2);
				end;

			if (rLLNormal <= choice) and (choice <= rLLCustom) then
				lutType := choice;

			if (rLLLoadLUT = choice) then
				error := VDReadLUT(VDInputLut[CurrentLUT]);

		until (Done = true);

		DisposeDialog(LLDlog);

		{  Restore the grafport	}
		SetPort(oldPort);

		{  If the dialog was successful then update the information  }
		if (okay = true) then begin

			{  Initialize the screen update flag.  This is used to indicate if an option change		}
			{  requires a new document to be allocated.																														}
				update := false;

	 		{ Set the selected input LUT as the new input LUT. }
				SelLUT := CurrentLUT;
				error := SetVDigitizerInLUT(CurrentLUT);

			{  Update the parameters	}
				VDInputLut[CurrentLUT].kind := lutType;
				VDInputLut[CurrentLUT].threshold := threshold;
				VDInputLut[CurrentLUT].brightness := brightness;
				VDInputLut[CurrentLUT].contrast := contrast;

			{ And load the selected LUT with the selected pattern. }
				LoadInputLookupTable;
			end;
		HUnlock(Handle(CurrentVDigitizer));

	end;		{ DoLoadLUTDlog }


	procedure ShowModeList (theDlgPtr: DialogPtr; var theList: ListHandle);
		const
			rSMUserItem = 4;
		var
			rView, dataBounds: Rect;
			cSize, theCell: Point;
			itemType: integer;
			itemHandle: handle;
			status: OSErr;
			nModes, firstRow, i, theLength: integer;
			theModeName: Str255;
			thePtr: Ptr;
	begin

		{  Set up the parameters for the list  }
		GetDialogItem(theDlgPtr, rSMUserItem, itemType, itemHandle, rView);
		SetRect(dataBounds, 0, 0, 1, 0);
		SetPt(cSize, 0, 0);
		theList := LNew(rView, dataBounds, cSize, 0, theDlgPtr, true, false, false, true);

		if theList <> nil then begin

				{  Set up the box for the list}
				InsetRect(rView, -1, -1);
				FrameRect(rView);
				theCell.h := 0;
				status := GetVDigitizerNumModes(nModes);
				firstRow := LAddRow(nModes, 1, theList);

				{  Put the names into the list  }
				for i := 0 to nModes - 1 do begin
						status := GetVDigitizerModeName(i + 1, theModeName);
						theLength := Integer(theModeName[0]);
						thePtr := Ptr(ord4(@theModeName[1]));
						theCell.v := i;
						LSetCell(thePtr, theLength, theCell, theList);
					end;  {for i := 0 to }

				{  Select the current mode  }
				status := GetVDigitizerMode(nModes);
				theCell.v := nModes - 1;
				LSetSelect(true, theCell, theList);
			end;  {if theList <> nil}

	end;  {procedure ShowModeList}


	{NOTE:This procedure can only be used if the three radio buttons are sequential dialog items}
	procedure UpdateRadioGroup (theDlogPtr: DialogPtr; theFirstButton: integer; theChoice: integer);
	begin
		DSSetIRadio(theDlogPtr, theFirstButton + 0, theChoice = (theFirstButton + 0));
		DSSetIRadio(theDlogPtr, theFirstButton + 1, theChoice = (theFirstButton + 1));
		DSSetIRadio(theDlogPtr, theFirstButton + 2, theChoice = (theFirstButton + 2));
	end;


	procedure DoCohuModalDlog;
		const
			rCohuModalDlog = 11222;
			rChoice0 = 4;
			rChoice1 = 5;
			rChoice2 = 6;
		var
			oldPort: GrafPtr;
			choice, theSelection: integer;
			CMDlogPtr: DialogPtr;
			status: OSErr;
			theMPListHdl: VDMPListHdl;
			ItemType: integer;
			ItemBox: rect;
			ItemHdl: handle;
	begin
		{  Save the current Grafport.		}
		GetPort(oldPort);

    {  Get the dialog.   }
		CMDlogPtr := DSGetNewDialog(rCohuModalDlog, nil, pointer(-1));
		SetPort(CMDlogPtr);

		{  Initialize the radio buttons  }
		theMPListHdl := VDMPListHdl(NewHandle(sizeof(VDModalParamsList)));
		status := GetVDigitizerModalParams(theMPListHdl);
		hlock(handle(theMPListHdl));

		theSelection := rChoice0 + theMPListHdl^^.vdModalParams[0].vdMPIEntryValue - 1;
		choice := theSelection;

		ShowWindow(CMDlogPtr);
		OutlineButton(CMDlogPtr, ok, 16);

		{ Loop to process user inputs for the dialog. }
		repeat

			if (rChoice0 <= choice) and (choice <= rChoice2) then begin
					theSelection := choice;
					UpdateRadioGroup(CMDlogPtr, rChoice0, theSelection);
				end;

			ModalDialog(nil, choice);

		until (choice = OK) or (choice = cancel);

		if choice = OK then begin
				theMPListHdl^^.vdModalParams[0].vdMPIEntryValue := theSelection - rChoice0 + 1;
				status := SetVDigitizerModalParams(theMPListHdl);
			end;  {if item = OK}

		{  Cleanup the memory  }
		hunlock(handle(theMPListHdl));
		DisposeHandle(handle(theMPListHdl));

		{  Restore the grafport	}
		DisposeDialog(CMDlogPtr);
		SetPort(oldPort);

	end;

	procedure DoModalParamDlog;
		const
			rModalParamDlog = 11221;
			rDlogName = 3;
			rChoice00 = 5;
			rChoice01 = 6;
			rChoice02 = 7;
			rChoice10 = 9;
			rChoice11 = 10;
			rChoice12 = 11;
			rChoice20 = 13;
			rChoice21 = 14;
			rChoice22 = 15;
			rEntry0Name = 4;
			rEntry1Name = 8;
			rEntry2Name = 12;
			rEntry3Name = 16;
			rShutterValue = 17;
			rShutterMin = 19;
			rShutterSlider = 20;
			rShutterMax = 21;
			nNames = 3;
		var
			oldPort: GrafPtr;
			MPDlogPtr: DialogPtr;
			choice, ctr1, ctr2, item, nParams: integer;
			selGroup0, selGroup1, selGroup2: integer;
			nChoices: array[0..nNames] of integer;
			status: OSErr;
			tmpStr: Str255;
			itemType: integer;
			itemHandle: handle;
			itemRect: Rect;
			tmpExt1, tmpExt2, tmpExt3, conversionFactor: LongReal;
			shutterSlider: SliderInfo;
			theMPListHdl: VDMPListHdl;
			theMPSize: longInt;
			myEventFilterProc: ModalFilterUPP;
	begin
		{  Save the current Grafport.		}
		theMPSize := sizeof(VDModalParamsList);
		theMPListHdl := VDMPListHdl(NewHandle(sizeof(VDModalParamsList)));
		status := GetVDigitizerModalParams(theMPListHdl);
		GetPort(oldPort);

    {  Get the dialog.   }
		MPDlogPtr := DSGetNewDialog(rModalParamDlog, nil, pointer(-1));
		SetPort(MPDlogPtr);
		
		{  For PPC:  Get a routine descriptor for our dialog event filter proc so we can
			 call it in a mixed mode environment. }
		myEventFilterProc := NewModalFilterProc(@DSEventFilter);

		{  Put the labels on the dialog  }
		tmpStr := theMPListHdl^^.vdMPListName;
		SetDString(MPDlogPtr, rDlogName, tmpStr);
		nParams := theMPListHdl^^.vdMPNParams;
		for ctr1 := 0 to nNames do begin
				if ctr1 > nParams - 2 then
					HideDialogItem(MPDlogPtr, rEntry0Name + ctr1 * 4)
				else begin
						tmpStr := theMPListHdl^^.vdModalParams[ctr1].vdMPEntryName;
						SetDString(MPDlogPtr, rEntry0Name + ctr1 * 4, tmpStr);
						ShowDialogItem(MPDlogPtr, rEntry0Name + ctr1 * 4);
						if ctr1 < 3 then begin
								nChoices[ctr1] := theMPListHdl^^.vdModalParams[ctr1].vdMPNChoices;
								for ctr2 := 1 to 3 do
									if ctr2 > nChoices[ctr1] then
										HideDialogItem(MPDlogPtr, rEntry0Name + ctr1 * 4 + ctr2)
									else begin
											tmpStr := theMPListHdl^^.vdModalParams[ctr1].vdMPChoiceNames[ctr2 - 1];
											GetDialogItem(MPDlogPtr, rEntry0Name + ctr1 * 4 + ctr2, itemType, itemHandle, itemRect);
											SetControlTitle(ControlHandle(itemHandle), tmpStr);
											ShowDialogItem(MPDlogPtr, rEntry0Name + ctr1 * 4 + ctr2);
										end;  {for ctr2 := 1}
							end;  {if ctr1 < 3}
					end;  {for ctr1 := 0}
			end;

		tmpExt2 := theMPListHdl^^.vdModalParams[3].vdMPFMinValue;
		tmpStr := StringOf(tmpExt2 : 5 : 3);
		SetDString(MPDlogPtr, rShutterMin, tmpStr);

		tmpExt3 := theMPListHdl^^.vdModalParams[3].vdMPFMaxValue;
		tmpStr := StringOf(tmpExt3 : 8 : 3);
		SetDString(MPDlogPtr, rShutterMax, tmpStr);

		{  Display the slider and its values  }
		tmpExt1 := theMPListHdl^^.vdModalParams[3].vdMPFEntryValue;
		GetDialogItem(MPDlogPtr, rShutterSlider, itemType, itemHandle, itemRect);
		SetControlMinimum(ControlHandle(itemHandle), -(gMaxInt - 1));
		SetControlMaximum(ControlHandle(itemHandle), gMaxInt - 1);
		conversionFactor := tmpExt2 / 2.0;
		DSSetSliderInfo(shutterSlider, MPDlogPtr, rShutterSlider, 1, 100, 8, @DSTimeSliderToText, rShutterValue, tmpExt2, tmpExt3, conversionFactor);
		tmpStr := StringOf(tmpExt1 : 8 : 3);
		SetDString(MPDlogPtr, rShutterValue, tmpStr);
		DSTimeTextToSlider(MPDlogPtr, shutterSlider.theSlider, rShutterValue);
		SelectDialogItemText(MPDlogPtr, rShutterValue, 0, gMaxInt);

{  Initialize the radio buttons  }
		selGroup0 := rChoice00 + theMPListHdl^^.vdModalParams[0].vdMPIEntryValue - 1;
		UpdateRadioGroup(MPDlogPtr, rChoice00, selGroup0);

		selGroup1 := rChoice10 + theMPListHdl^^.vdModalParams[1].vdMPIEntryValue - 1;
		UpdateRadioGroup(MPDlogPtr, rChoice10, selGroup1);

		selGroup2 := rChoice20 + theMPListHdl^^.vdModalParams[2].vdMPIEntryValue - 1;
		UpdateRadioGroup(MPDlogPtr, rChoice20, selGroup2);

		ShowWindow(MPDlogPtr);
		OutlineButton(MPDlogPtr, ok, 16);

		{ Loop to process user inputs for the dialog. }
		repeat

			ModalDialog(myEventFilterProc, choice);
			{ModalDialog(nil, choice);}

			if choice = rShutterValue then begin
					GetDialogItem(MPDlogPtr, rShutterSlider, itemType, itemHandle, itemRect);
					DSTimeTextToSlider(MPDlogPtr, ControlHandle(itemHandle), choice);
				end;

			if choice = rShutterSlider then begin
					GetDialogItem(MPDlogPtr, choice, itemType, itemHandle, itemRect);
					DSTimeSliderToText(MPDlogPtr, ControlHandle(itemHandle), GetControlValue(ControlHandle(itemHandle)), rShutterValue);
				end;

			if (rChoice00 <= choice) and (choice <= rChoice02) then begin
					selGroup0 := choice;
					UpdateRadioGroup(MPDlogPtr, rChoice00, selGroup0);
				end;

			if (rChoice10 <= choice) and (choice <= rChoice12) then begin
					selGroup1 := choice;
					UpdateRadioGroup(MPDlogPtr, rChoice10, selGroup1);
				end;

			if (rChoice20 <= choice) and (choice <= rChoice22) then begin
					selGroup2 := choice;
					UpdateRadioGroup(MPDlogPtr, rChoice20, selGroup2);
				end;

		until (choice = OK) or (choice = cancel);

		if choice = OK then begin
				theMPListHdl^^.vdModalParams[0].vdMPIEntryValue := selGroup0 - rChoice00 + 1;
				theMPListHdl^^.vdModalParams[1].vdMPIEntryValue := selGroup1 - rChoice10 + 1;
				theMPListHdl^^.vdModalParams[2].vdMPIEntryValue := selGroup2 - rChoice20 + 1;
				theMPListHdl^^.vdModalParams[3].vdMPFEntryValue := GetDReal(MPDlogPtr, rShutterValue);
				status := SetVDigitizerModalParams(theMPListHdl);
			end;  {if choice = OK}

		{  Cleanup the memory  }
		DisposeHandle(handle(theMPListHdl));

		{  Restore the grafport	}
		DisposeDialog(MPDlogPtr);
		SetPort(oldPort);

	end;


	procedure DoSetModeDlog;
		const
			rSetModeDlog = 11220;

		var
			result: boolean;
			oldPort: GrafPtr;
			SMDlogPtr: DialogPtr;
			item, nModes: integer;
			theList: ListHandle;
			theCell: Cell;
			status: OSErr;
			myEventFilterProc: ModalFilterUPP;

	begin
		{  Save the current Grafport.		}
		GetPort(oldPort);

    {  Get the dialog.   }
		SMDlogPtr := DSGetNewDialog(rSetModeDlog, nil, pointer(-1));
		SetPort(SMDlogPtr);

		{  Show the list of available modes  }
		ShowModeList(SMDlogPtr, theList);
		WindowPeek(SMDlogPtr)^.refCon := LongInt(theList);

		ShowWindow(SMDlogPtr);
		OutlineButton(SMDlogPtr, ok, 16);

		{  For PPC:  Get a routine descriptor for our dialog event filter proc so we can
			 call it in a mixed mode environment. }
		myEventFilterProc := NewModalFilterProc(@DSListFilterProc);


		{ Loop to process user inputs for the dialog. }
		repeat

			ModalDialog(myEventFilterProc, item);

		until (item = OK) or (item = cancel);

		if item = OK then begin
				theCell := LLastClick(theList);
				if (theCell.h >= 0) and (theCell.v >= 0) then begin
						status := GetVDigitizerNumModes(nModes);
						if nModes >= theCell.v + 1 then
							status := SetVDigitizerMode(theCell.v + 1);
					end;  {if (theCell.h >= 0)}
			end;  {if item = OK}

		{  Restore the grafport	}
		DisposeDialog(SMDlogPtr);
		SetPort(oldPort);

	end;


	procedure WriteOfXOnDlog (theDialog: DialogPtr; theItem: Integer; theValue: Integer);
		var
			theStr: Str255;

	begin
		NumToString(theValue, theStr);
		theStr := concat('(of ', theStr);
		theStr := concat(theStr, ')');
		SetDString(theDialog, theItem, theStr);
	end;


	procedure ControlModeButton;
		var
			status: OSErr;
			tempInt: Integer;
			ItemType: integer;
			ItemBox: rect;
			ItemHdl: handle;
			CurrentVDigitizer: VDHandle;
	begin
		CurrentVDigitizer := GetActiveVDigitizer;
		status := GetVDigitizerNumModes(tempInt);
		GetDialogItem(VideoControl, SetModeID, ItemType, ItemHdl, ItemBox);
		if (tempInt < 2) and (CurrentVDigitizer^^.vdModeInfo.vdMPListHdl = nil) then
			HiliteControl(ControlHandle(ItemHdl), 255)
		else
			HiliteControl(ControlHandle(ItemHdl), 0);
	end;


	procedure AddNUBSResourceInfo;
		var
			NUBSInfoH, NUBShdl: NUBSInfoHandle;
			NUBSInfoP, newNUBSP: NUBSInfoPtr;
			size, newSize: LongInt;
			resFileRefNum: integer;
			found: boolean;
	begin
		NUBSHdl := nil;
		NUBSInfoH := NUBSInfoHandle(GetResource('NUBS', 0));
		if (NUBSInfoH = nil) then begin
				NUBSHdl := NUBSInfoHandle(NewHandle(SizeOF(NUBSInfoRec) * 2));
				HLock(Handle(NUBSHdl));
				NUBSInfoP := NUBSHdl^;
				NUBSInfoP^.vdevMaxWidth := vdevNUBSInfo.vdevMaxWidth;
				NUBSInfoP^.vdevMonitorName := vdevNUBSInfo.vdevMonitorName;
				NUBSInfoP^.vdevID := vdevNUBSInfo.vdevID;
				NUBSInfoP := NUBSInfoPtr(ord4(NUBSInfoP) + SizeOf(NUBSInfoRec));
				NUBSInfoP^.vdevMaxWidth := 1024;
				NUBSInfoP^.vdevMonitorName := ' ';
				NUBSInfoP^.vdevID := 0;
				NUBSInfoH := NUBSHdl;
				HUnlock(Handle(NUBSHdl));
			end
		else begin

				HLock(Handle(NUBSInfoH));
				size := GetHandleSize(Handle(NUBSInfoH));
				NUBSInfoP := NUBSInfoH^;

				found := false;
				while (NUBSInfoP^.vdevID <> 0) and (not found) do begin
						if (NUBSInfoP^.vdevID = vdevNUBSInfo.vdevID) then begin
								NUBSInfoP^.vdevMaxWidth := vdevNUBSInfo.vdevMaxWidth;
								NUBSInfoP^.vdevMonitorName := vdevNUBSInfo.vdevMonitorName;
								NUBSInfoP^.vdevID := vdevNUBSInfo.vdevID;
								found := true;
							end;
						NUBSInfoP := NUBSInfoPtr(ord4(NUBSInfoP) + SizeOf(NUBSInfoRec));
					end;

				if (not found) then begin
						NUBSInfoP^.vdevMaxWidth := vdevNUBSInfo.vdevMaxWidth;
						NUBSInfoP^.vdevMonitorName := vdevNUBSInfo.vdevMonitorName;
						NUBSInfoP^.vdevID := vdevNUBSInfo.vdevID;
						newsize := size + SizeOF(NUBSInfoRec);
						NUBSHdl := NUBSInfoHandle(NewHandle(newSize));
						HLock(Handle(NUBSHdl));
						NUBSInfoP := NUBSInfoH^;
						newNUBSP := NUBSHdl^;
						BlockMove(Ptr(NUBSInfoP), Ptr(newNUBSP), size);
						NUBSInfoP := NUBSHdl^;
						NUBSInfoP := NUBSInfoPtr(ord4(NUBSInfoP) + size);
						NUBSInfoP^.vdevMaxWidth := 1024;
						NUBSInfoP^.vdevMonitorName := '';
						NUBSInfoP^.vdevID := 0;
						HUnlock(Handle(NUBSInfoH));
						RemoveResource(Handle(NUBSInfoH));
						ReleaseResource(Handle(NUBSInfoH));
						NUBSInfoH := NUBSHdl;
						HLock(Handle(NUBSInfoH));
						HUnlock(Handle(NUBSHdl));
					end
				else
					RemoveResource(Handle(NUBSInfoH));

			end;
		AddResource(Handle(NUBSInfoH), 'NUBS', 0, '');
		if ResError <> NoErr then
			SysBeep(1);
		ChangedResource(Handle(NUBSInfoH));
		if ResError <> NoErr then
			SysBeep(1);
		WriteResource(Handle(NUBSInfoH));
		if ResError <> NoErr then
			SysBeep(1);
{    if (NUBSHdl <> nil) then}
{    DisposHandle(Handle(NUBSHdl));}
		HUnlock(Handle(NUBSInfoH));
	end;


	function GetNUBSResourceInfo (vDeviceID: integer): integer;
		var
			NUBSInfoH: NUBSInfoHandle;
			NUBSInfoP: NUBSInfoPtr;
			maxDmaWidth: integer;
			vdevNameStr: packed array[1..32] of char;
			p: ptr;
			i: integer;
	begin
		NUBSInfoH := NUBSInfoHandle(GetResource('NUBS', 0));
		if (ResError <> noErr) then begin
	{ Return 0 if video device not set up in NUBS Resource.	}
				GetNUBSResourceInfo := 0;
			end
		else begin
				HNoPurge(Handle(NUBSInfoH));
				vdevNUBSInfo.vdevID := 0;
				GetNUBSResourceInfo := 0;

				NUBSInfoP := NUBSInfoH^;
				while (NUBSInfoP^.vdevID <> 0) and (vdevNUBSInfo.vdevID = 0) do begin
						if (NUBSInfoP^.vdevID = vDeviceID) then begin
								vdevNUBSInfo.vdevMaxWidth := NUBSInfoP^.vdevMaxWidth;
								vdevNUBSInfo.vdevMonitorName := NUBSInfoP^.vdevMonitorName;
								vdevNUBSInfo.vdevID := vDeviceID;
								GetNUBSResourceInfo := vDeviceID;
							end;
						NUBSInfoP := NUBSInfoPtr(ord4(NUBSInfoP) + SizeOf(NUBSInfoRec));
					end;

			end;
	end;


	procedure ConfigureMonitor;
		var
			gDevHandle: GDHandle;
			dCEHandle: AuxDCEHandle;
			message: str255;
			vDevId: integer;
			item: integer;
			myDLOG: DialogPtr;
			oldPort: GrafPtr;
			nubsStatus: integer;
	begin

		GetPort(oldPort);
		{ Open a dialog box and fill it in using the info from the VDigitizer list. }
		myDLOG := DSGetNewDialog(13002, nil, pointer(-1));

{ Get the Monitor Id from the resource }
		gDevHandle := GetMainDevice;
		dCEHandle := AuxDCEHandle(GetDCtlEntry(gDevHandle^^.gdRefNum));

{ Find the Id in the NUBS resource}
		vDevID := GetSlotId(dCEHandle^^.dCtlSlot);
		nubsStatus := GetNUBSResourceInfo(vDevID);

		SetPort(myDLOG);
		OutlineButton(myDLOG, ok, 16);

{ If the Id is Not in the NUBS resource, set Text and set Id}
		if (nubsStatus = vDevId) then begin
				message := 'Current Video Device is defined as...';
				SetDString(myDLOG, vDevTextID, message);
				SetDNum(myDLOG, vDevMonitorIdID, vDevID);
				SetDNum(myDLOG, vDevMaxWidthID, vdevNUBSInfo.vdevMaxWidth);
				SetDString(myDLOG, vDevMonitorNameID, vdevNUBSInfo.vdevMonitorName);
			end
		else begin
				message := 'The current Video Device is not defined in the resource file, please enter the Maximum Width for DMA and the Device Name.';
				SetDString(myDLOG, vDevTextID, message);
				SetDString(myDLOG, vDevMonitorIdID, StringOf(vDevID));
				SetDNum(myDLOG, vDevMaxWidthID, 0);
				SetDString(myDLOG, vDevMonitorNameID, ' ');
			end;

		repeat
			ModalDialog(nil, item);
		until (item = ok) or (item = cancel);
		if (item = ok) then begin
				vdevNUBSInfo.vdevID := GetDNum(myDLOG, vDevMonitorIdID);
				vdevNUBSInfo.vdevMaxWidth := GetDNum(myDLOG, vDevMaxWidthID);
				vdevNUBSInfo.vdevMonitorName := GetDString(myDLOG, vDevMonitorNameID);
				AddNUBSResourceInfo;
			end;

		DisposeDialog(myDLOG);
		SetPort(oldport);
	end;


	procedure ConfigureCameraInfo;
		const
			camera14ID = 3;
			camera42ID = 4;
			camera16ID = 5;
			cameraOtherID = 6;
			cameraWidthID = 7;
			cameraHeightID = 8;
			cameraTopEdgeID = 9;
			cameraLeftEdgeID = 10;
			cameraBottomEdgeID = 11;
			cameraRightEdgeID = 12;
			cameraBitsPerPixelID = 14;
			cameraPixelOffsetID = 15;
			cameraBitsToShiftID = 16;
			cameraLineTimeID = 17;
			cameraNameID = 13;
		var
			cameraType, cameraWidth, cameraHeight: Integer;
			cameraTopEdge, cameraLeftEdge, cameraBottomEdge, cameraRightEdge: Integer;
			cameraDepth, cameraPixelOffset, cameraBitsToShift, cameraLineTime: Integer;
			cameraSpecialInfo: Integer;
			cameraName: Str31;
			cameraSize: Point;
			edgesRect: Rect;
			item: integer;
			myDLOG: DialogPtr;
			oldPort: GrafPtr;
			status: OSErr;
	begin

		GetPort(oldPort);
		{ Open a dialog box and fill it in using the info from the VDigitizer. }
		myDLOG := DSGetNewDialog(13004, nil, pointer(-1));
		SetPort(myDLOG);

		{ Get the current camera info }
		cameraType := gvdCameraSelection;
		cameraWidth := gvdCameraWidth;
		cameraHeight := gvdCameraHeight;
		cameraLeftEdge := gvdCameraLeftEdge;
		cameraTopEdge := gvdCameraTopEdge;
		cameraRightEdge := gvdCameraRightEdge;
		cameraBottomEdge := gvdCameraBottomEdge;
		cameraName := gvdCameraName;
		cameraLineTime := gvdCameraLineTime;
		cameraDepth := gvdCameraDepth;
		cameraPixelOffset := gvdCameraPixelOffset;
		cameraBitsToShift := gvdCameraBitsToShift;
		cameraSpecialInfo := gvdCameraSpecialInfo;

		{ Update the dialog fields based on current info }
		DSSetIRadio(myDLOG, camera14ID, false);
		DSSetIRadio(myDLOG, camera42ID, false);
		DSSetIRadio(myDLOG, camera16ID, false);
		DSSetIRadio(myDLOG, cameraOtherID, false);
		if (cameraType = 1) then
			DSSetIRadio(myDLOG, camera42ID, true)
		else if (cameraType = 2) then
			DSSetIRadio(myDLOG, camera16ID, true)
		else if (cameraType = 3) then
			DSSetIRadio(myDLOG, cameraOtherID, true)
		else
			DSSetIRadio(myDLOG, camera14ID, true);

		SetDNum(myDLOG, cameraWidthID, cameraWidth);
		SetDNum(myDLOG, cameraHeightID, cameraHeight);
		SetDNum(myDLOG, cameraTopEdgeID, cameraTopEdge);
		SetDNum(myDLOG, cameraLeftEdgeID, cameraLeftEdge);
		SetDNum(myDLOG, cameraBottomEdgeID, cameraBottomEdge);
		SetDNum(myDLOG, cameraRightEdgeID, cameraRightEdge);
		SetDNum(myDLOG, cameraBitsPerPixelID, cameraDepth);
		SetDNum(myDLOG, cameraPixelOffsetID, cameraPixelOffset);
		SetDNum(myDLOG, cameraBitsToShiftID, cameraBitsToShift);
		SetDNum(myDLOG, cameraLineTimeID, cameraLineTime);
		SetDString(myDLOG, cameraNameID, cameraName);

		OutlineButton(myDLOG, ok, 16);

		repeat
			ModalDialog(nil, item);

			if (item >= camera14ID) and (item <= cameraOtherID) then begin
					DSSetIRadio(myDLOG, camera14ID, false);
					DSSetIRadio(myDLOG, camera42ID, false);
					DSSetIRadio(myDLOG, camera16ID, false);
					DSSetIRadio(myDLOG, cameraOtherID, false);
					if (item = camera14ID) then
						DSSetIRadio(myDLOG, camera14ID, true)
					else if (item = camera42ID) then
						DSSetIRadio(myDLOG, camera42ID, true)
					else if (item = camera16ID) then
						DSSetIRadio(myDLOG, camera16ID, true)
					else if (item = cameraOtherID) then
						DSSetIRadio(myDLOG, cameraOtherID, true);
					cameraType := item - camera14ID;
					with vdGlobalSettings do begin
							cameraWidth := vdBoardSettings[vdBoardIndex].vdCameraWidth[cameraType];
							cameraHeight := vdBoardSettings[vdBoardIndex].vdCameraHeight[cameraType];
							cameraLeftEdge := vdBoardSettings[vdBoardIndex].vdCameraLeftEdge[cameraType];
							cameraTopEdge := vdBoardSettings[vdBoardIndex].vdCameraTopEdge[cameraType];
							cameraRightEdge := vdBoardSettings[vdBoardIndex].vdCameraRightEdge[cameraType];
							cameraBottomEdge := vdBoardSettings[vdBoardIndex].vdCameraBottomEdge[cameraType];
							cameraName := vdBoardSettings[vdBoardIndex].vdCameraName[cameraType];
							cameraLineTime := vdBoardSettings[vdBoardIndex].vdCameraLineTime[cameraType];
							cameraDepth := vdBoardSettings[vdBoardIndex].vdCameraDepth[cameraType];
							cameraPixelOffset := vdBoardSettings[vdBoardIndex].vdCameraPixelOffset[cameraType];
							cameraBitsToShift := vdBoardSettings[vdBoardIndex].vdCameraBitsToShift[cameraType];
						end;
					SetDNum(myDLOG, cameraWidthID, cameraWidth);
					SetDNum(myDLOG, cameraHeightID, cameraHeight);
					SetDNum(myDLOG, cameraTopEdgeID, cameraTopEdge);
					SetDNum(myDLOG, cameraLeftEdgeID, cameraLeftEdge);
					SetDNum(myDLOG, cameraBottomEdgeID, cameraBottomEdge);
					SetDNum(myDLOG, cameraRightEdgeID, cameraRightEdge);
					SetDNum(myDLOG, cameraBitsPerPixelID, cameraDepth);
					SetDNum(myDLOG, cameraPixelOffsetID, cameraPixelOffset);
					SetDNum(myDLOG, cameraBitsToShiftID, cameraBitsToShift);
					SetDNum(myDLOG, cameraLineTimeID, cameraLineTime);
					SetDString(myDLOG, cameraNameID, cameraName);
				end;

		until (item = ok) or (item = cancel);

		if (item = ok) then begin
				gvdCameraSelection := cameraType;
				cameraWidth := GetDNum(myDLOG, cameraWidthID);
				cameraHeight := GetDNum(myDLOG, cameraHeightID);
				cameraLeftEdge := GetDNum(myDLOG, cameraLeftEdgeID);
				cameraTopEdge := GetDNum(myDLOG, cameraTopEdgeID);
				cameraRightEdge := GetDNum(myDLOG, cameraRightEdgeID);
				cameraBottomEdge := GetDNum(myDLOG, cameraBottomEdgeID);
				cameraName := GetDString(myDLOG, cameraNameID);
				cameraLineTime := GetDNum(myDLOG, cameraLineTimeID);
				cameraDepth := GetDNum(myDLOG, cameraBitsPerPixelID);
				cameraPixelOffset := GetDNum(myDLOG, cameraPixelOffsetID);
				cameraBitsToShift := GetDNum(myDLOG, cameraBitsToShiftID);
				status := SetVDigitizerCamera(cameraType);
				SetPt(cameraSize, cameraWidth, cameraHeight);
				status := SetVDigitizerCameraSize(cameraSize);
				SetRect(edgesRect, cameraLeftEdge, cameraTopEdge, cameraRightEdge, cameraBottomEdge);
				status := SetVDigitizerCameraEdges(edgesRect);
				status := SetVDigitizerCameraName(cameraName);
				status := SetVDigitizerCameraLineTime(cameraLineTime);
				status := SetVDigitizerCameraPixelInfo(cameraDepth, cameraPixelOffset, cameraBitsToShift);
				gvdCameraWidth := cameraWidth;
				gvdCameraHeight := cameraHeight;
				gvdCameraLeftEdge := cameraLeftEdge;
				gvdCameraTopEdge := cameraTopEdge;
				gvdCameraRightEdge := cameraRightEdge;
				gvdCameraBottomEdge := cameraBottomEdge;
				gvdCameraName := cameraName;
				gvdCameraLineTime := cameraLineTime;
				gvdCameraDepth := cameraDepth;
				gvdCameraPixelOffset := cameraPixelOffset;
				gvdCameraBitsToShift := cameraBitsToShift;
				with vdGlobalSettings do begin
						vdBoardSettings[vdBoardIndex].vdCameraSelection := gvdCameraSelection;
						vdBoardSettings[vdBoardIndex].vdCameraWidth[gvdCameraSelection] := gvdCameraWidth;
						vdBoardSettings[vdBoardIndex].vdCameraHeight[gvdCameraSelection] := gvdCameraHeight;
						vdBoardSettings[vdBoardIndex].vdCameraLeftEdge[gvdCameraSelection] := gvdCameraLeftEdge;
						vdBoardSettings[vdBoardIndex].vdCameraTopEdge[gvdCameraSelection] := gvdCameraTopEdge;
						vdBoardSettings[vdBoardIndex].vdCameraRightEdge[gvdCameraSelection] := gvdCameraRightEdge;
						vdBoardSettings[vdBoardIndex].vdCameraBottomEdge[gvdCameraSelection] := gvdCameraBottomEdge;
						vdBoardSettings[vdBoardIndex].vdCameraName[gvdCameraSelection] := gvdCameraName;
						vdBoardSettings[vdBoardIndex].vdCameraLineTime[gvdCameraSelection] := gvdCameraLineTime;
						vdBoardSettings[vdBoardIndex].vdCameraDepth[gvdCameraSelection] := gvdCameraDepth;
						vdBoardSettings[vdBoardIndex].vdCameraPixelOffset[gvdCameraSelection] := gvdCameraPixelOffset;
						vdBoardSettings[vdBoardIndex].vdCameraBitsToShift[gvdCameraSelection] := gvdCameraBitsToShift;
					end;
			end;

		DisposeDialog(myDLOG);
		SetPort(oldport);
	end;


	procedure ShowVDChannel (CurrentChannel, NChannels: Integer);
		var
			channel, ItemType: integer;
			ItemBox: rect;
			ItemHdl: handle;
	begin
		if NChannels < 1 then
			NChannels := 1;
		if NChannels > 4 then
			NChannels := 4;
		if CurrentChannel < 1 then
			CurrentChannel := 1;
		if CurrentChannel > 4 then
			CurrentChannel := 1;
		for channel := 1 to NChannels do begin
				GetDialogItem(VideoControl, FirstChannelID + channel - 1, ItemType, ItemHdl, ItemBox);
				HiliteControl(ControlHandle(ItemHdl), 0);
				if channel = CurrentChannel then
					SetControlValue(ControlHandle(ItemHdl), 1)
				else
					SetControlValue(ControlHandle(ItemHdl), 0)
			end;
		if NChannels < 4 then begin
				for channel := NChannels to 4 do begin
						GetDialogItem(VideoControl, FirstChannelID + channel - 1, ItemType, ItemHdl, ItemBox);
						HiliteControl(ControlHandle(ItemHdl), 255);
					end;
			end;
	end;


	procedure ShowOffsetAndGain;
		var
			str: str255;
			currentGain, currentOffset: Real;
			error: OSErr;
			hasCtrl: Boolean;
	begin
		{ Get current values for gain and offset. }
		error := TestVDigitizerFeature(nil, vdFeBProgGain, hasCtrl);
		if hasCtrl then begin
				error := GetVDigitizerGain(currentGain);
				if (error <> noErr) then begin
						exit(ShowOffsetAndGain);
					end;
			end
		else
			currentGain := 0.0;
		error := TestVDigitizerFeature(nil, vdFeBProgGain, hasCtrl);
		if hasCtrl then begin
				error := GetVDigitizerOffset(currentOffset);
				if error <> noErr then begin
						exit(ShowOffsetAndGain);
					end;
			end
		else
			currentOffset := 0.0;

		RealToString(currentOffset, 7, 4, str);
		SetDString(VideoControl, OffsetID, str);
		RealToString(currentGain, 5, 2, str);
		SetDString(VideoControl, GainID, str);
	end;


	procedure RefreshVideoControl;
		var
			tempInt, CurrentLUT, NChannels, CurrentChannel: integer;
			ItemType, i: integer;
			ItemBox: rect;
			ItemHdl: handle;
			status: OSErr;
			hasCtrl: boolean;
			CurrentVDigitizer, VDigHandle: VDHandle;
			savePort: GrafPtr;
	begin
		InitCursor;
		GetPort(savePort);
		SetPort(GrafPtr(VideoControl));
		EraseRect(GrafPtr(VideoControl)^.portRect);
		DrawDialog(VideoControl);
		CurrentVDigitizer := GetActiveVDigitizer;

		{ Update the digitizer selections in the dialog.}
		VDigHandle := GetFirstVDigitizer;
		for i := 0 to 2 do begin
				if VDigHandle <> nil then begin
						HLock(Handle(VDigHandle));
						GetDialogItem(VideoControl, VDChoice1ID + i, ItemType, ItemHdl, ItemBox);
						if CurrentVDigitizer = VDigHandle then begin
								SetControlValue(DigitizerSel[i], 1);
							end
						else begin
								SetControlValue(DigitizerSel[i], 0);
							end;
						HUnlock(Handle(VDigHandle));
						VDigHandle := GetNthVDigitizer(i + 1);
					end;  { if VDigHandle <> nil }
			end;  { for i := 0 to 2 }

		if CurrentVDigitizer <> nil then begin

			{  Display the Input LUT info / selection}
				status := GetVDigitizerNumInLUTs(nil, tempInt);
				WriteOfXOnDlog(VideoControl, NumInLUTsID, tempInt);
				status := GetVDigitizerInLUT(CurrentLUT);
				if (CurrentLUT < 1) or (CurrentLUT > 10) then
					CurrentLUT := 1;
				SetDNum(VideoControl, InLUTNumStatID, LongInt(CurrentLUT));
				GetDialogItem(VideoControl, LoadInputLUTID, ItemType, ItemHdl, ItemBox);
				if tempInt <> 0 then
					HiliteControl(ControlHandle(ItemHdl), 0)
				else
					HiliteControl(ControlHandle(ItemHdl), 255);

			{  Update the Input Channel radio buttons}
				status := GetVDigitizerNumChannels(nil, NChannels);
				status := GetVDigitizerSrc(CurrentChannel);
				ShowVDChannel(CurrentChannel, NChannels);

				SetDlogItem(VideoControl, HighlightID, ord(HighlightSaturatedPixels));
				SetDlogItem(VideoControl, OscillatingID, ord(OscillatingMovies));
				SetDlogItem(VideoControl, BlindID, ord(BlindMovieCapture));

		{  Enable/Disable and set/clear the external trigger checkbox}
				status := TestVDigitizerControl(nil, vdFcBExtTrigStart + vdFcBExtTrigStop + vdFcBExtTrigStartStop, hasCtrl);
				if hasCtrl then begin
						GetDialogItem(VideoControl, TriggerID, ItemType, ItemHdl, ItemBox);
						HiliteControl(ControlHandle(ItemHdl), 0);
						if (gExtTrigger = vdExternalStart) or (gExtTrigger = vdExternalStartStop) then
							SetDlogItem(VideoControl, TriggerID, 1)
						else
							SetDlogItem(VideoControl, TriggerID, 0);
					end
				else begin
						gExtTrigger := vdSource;
						SetDlogItem(VideoControl, TriggerID, 0);
						GetDialogItem(VideoControl, TriggerID, ItemType, ItemHdl, ItemBox);
						HiliteControl(ControlHandle(ItemHdl), 255);
					end;

		{  Enable/Disable and set/clear the Use DMA Display checkbox}
				status := TestVDigitizerControl(nil, vdFcBDMAOut, hasCtrl);
				if hasCtrl then begin
						GetDialogItem(VideoControl, UseDMADisplayID, ItemType, ItemHdl, ItemBox);
						HiliteControl(ControlHandle(ItemHdl), 0);
						if (UseDMADisplay) then
							SetDlogItem(VideoControl, UseDMADisplayID, 1)
						else
							SetDlogItem(VideoControl, UseDMADisplayID, 0);
					end
				else begin
						status := TestVDigitizerFeature(nil, vdFeBDMAOut, hasCtrl);
						if (hasCtrl) then
							SetDlogItem(VideoControl, UseDMADisplayID, 1)
						else
							SetDlogItem(VideoControl, UseDMADisplayID, 0);
						GetDialogItem(VideoControl, UseDMADisplayID, ItemType, ItemHdl, ItemBox);
						HiliteControl(ControlHandle(ItemHdl), 255);
					end;

				GetDialogItem(VideoControl, StartCapturingID, itemType, ItemHdl, ItemBox);
				if digitizing then begin
{Change button to "Stop"}
						SetControlTitle(ControlHandle(ItemHdl), 'Stop');
					end
				else begin
{Change button to "Start"}
						SetControlTitle(ControlHandle(ItemHdl), 'Start');
					end;

				ControlModeButton;

				ShowOffsetAndGain;
			end
		else begin
				SetDlogItem(VideoControl, HighlightID, 0);
				GetDialogItem(VideoControl, HighlightID, ItemType, ItemHdl, ItemBox);
				HiliteControl(ControlHandle(ItemHdl), 255);
				SetDlogItem(VideoControl, OscillatingID, 0);
				GetDialogItem(VideoControl, OscillatingID, ItemType, ItemHdl, ItemBox);
				HiliteControl(ControlHandle(ItemHdl), 255);
				SetDlogItem(VideoControl, BlindID, 0);
				GetDialogItem(VideoControl, BlindID, ItemType, ItemHdl, ItemBox);
				HiliteControl(ControlHandle(ItemHdl), 255);
				SetDlogItem(VideoControl, TriggerID, 0);
				GetDialogItem(VideoControl, TriggerID, ItemType, ItemHdl, ItemBox);
				HiliteControl(ControlHandle(ItemHdl), 255);
				SetDlogItem(VideoControl, UseDMADisplayID, 0);
				GetDialogItem(VideoControl, UseDMADisplayID, ItemType, ItemHdl, ItemBox);
				HiliteControl(ControlHandle(ItemHdl), 255);
			end;
		SetPort(savePort);
	end;


	procedure ShowVideoControl;
		var
			i: integer;
			VDigHandle, CurrentVDigitizer, SaveVDigitizer: VDHandle;
			status: OSErr;
			ItemType: integer;
			ItemBox: rect;
			ItemHdl: handle;
			theModel: Str255;
	begin
		InitCursor;
		VideoControl := GetNewDialog(13001, nil, pointer(-1));

		{ Update the digitizer selections in the dialog.}
		VDigHandle := GetFirstVDigitizer;
		for i := 0 to 2 do begin
				DigitizerSel[i] := nil;
				if VDigHandle <> nil then begin
						HLock(Handle(VDigHandle));
						CurrentVDigitizer := GetActiveVDigitizer;
						SaveVDigitizer := CurrentVDigitizer;
						status := SetVDigitizer(VDigHandle);
						GetDialogItem(VideoControl, VDChoice1ID + i, ItemType, ItemHdl, ItemBox);

						status := GetVDigitizerModel(theModel);
						DigitizerSel[i] := NewControl(VideoControl, ItemBox, theModel, TRUE, 0, 0, 1, radioButProc, 1);
						if CurrentVDigitizer = VDigHandle then begin
								SetControlValue(DigitizerSel[i], 1);
							end
						else begin
								SetControlValue(DigitizerSel[i], 0);
							end;
						HUnlock(Handle(VDigHandle));
						VDigHandle := GetNthVDigitizer(i + 1);
						status := SetVDigitizer(SaveVDigitizer);
					end;  { if VDigHandle <> nil }
			end;  { for i := 0 to 3 }

		ShowWindow(VideoControl);
		RefreshVideoControl;
	end;


	procedure WriteDigitizerInfo (VDigHandle: VDHandle);
		var
			NumberStr, LabelStr, ModelStr, ModelNumberStr: Str255;
			tempInt: Integer;
			tempLong: LongInt;
			tempPoint: Point;
			DataRect: rect;
			status: OSErr;
			hasCtrl: boolean;
	begin
		TextFont(applFont);
		TextSize(9);
		SetRect(DataRect, 10, 23, 298, 210);
		EraseRect(DataRect);
		MoveTo(20, 35);
		if VDigHandle <> nil then begin
				status := GetVDigitizerSlot(tempInt);
				HexToString(tempInt, NumberStr, 1);
				status := GetVDigitizerModel(ModelStr);
				status := GetVDigitizerModelNumber(ModelNumberStr);
				LabelStr := concat('The digitizer in Slot ', NumberStr, ' is a: ');
				DrawString(LabelStr);
				MoveTo(30, 50);
				LabelStr := concat(ModelStr, ', Model ', ModelNumberStr);
				DrawString(LabelStr);

				MoveTo(20, 65);
				status := GetVDigitizerNumChannels(nil, tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(NumberStr, ' input channels, ');
				status := GetVDigitizerBitsPerChannel(nil, tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(LabelStr, NumberStr, '  bits per channel, ');
				status := GetVDigitizerNumBuffers(nil, tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(LabelStr, NumberStr, ' frame buffer');
				if tempInt > 1 then
					LabelStr := concat(LabelStr, 's');
				DrawString(LabelStr);

				MoveTo(20, 80);
				status := GetVDigitizerVideoSize(nil, tempPoint);
				NumToString(tempPoint.h, NumberStr);
				LabelStr := concat(NumberStr, ' x ');
				NumToString(tempPoint.v, NumberStr);
				LabelStr := concat(LabelStr, NumberStr, ' x ');
				status := GetVDigitizerBitsPerChannel(nil, tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(LabelStr, NumberStr);
				DrawString(LabelStr);

				MoveTo(20, 95);
				status := GetVDigitizerNumInLUTs(nil, tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(NumberStr, ' input LUTs, ');
				status := GetVDigitizerNumOutLUTs(nil, tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(LabelStr, NumberStr, ' output LUT');
				if tempInt <> 1 then
					LabelStr := concat(LabelStr, 's');
				DrawString(LabelStr);

				MoveTo(20, 110);
				status := GetVDigitizerNumModes(tempInt);
				NumToString(tempInt, NumberStr);
				LabelStr := concat(NumberStr, ' mode');
				if tempInt > 1 then begin
						LabelStr := concat(LabelStr, 's');
						status := GetVDigitizerMode(tempInt);
						status := GetVDigitizerModeName(tempInt, ModelStr);
						LabelStr := concat(LabelStr, ' (currently in ', ModelStr, ')');
					end;
				DrawString(LabelStr);

				MoveTo(20, 125);
				status := TestVDigitizerFeature(nil, vdFeBDMAOut, hasCtrl);
				if not hasCtrl then
					LabelStr := 'No '
				else
					LabelStr := '';
				LabelStr := concat(LabelStr, 'DMA, ');
				status := TestVDigitizerFeature(nil, vdFeBALU, hasCtrl);
				if not hasCtrl then
					LabelStr := concat(LabelStr, 'No ');
				LabelStr := concat(LabelStr, 'Pipeline Processor, ');
				status := TestVDigitizerFeature(nil, vdFeBProgGain, hasCtrl);
				if not hasCtrl then
					LabelStr := concat(LabelStr, 'No ');
				LabelStr := concat(LabelStr, 'Prog Gain, ');
				status := TestVDigitizerFeature(nil, vdFeBProgOffset, hasCtrl);
				if not hasCtrl then
					LabelStr := concat(LabelStr, 'No ');
				LabelStr := concat(LabelStr, 'Prog Offset ');
				DrawString(LabelStr);

				MoveTo(20, 140);
				LabelStr := 'Other:  ';
				DrawString(LabelStr);
				MoveTo(30, 155);
				status := GetVDigitizerDescription(ModelStr);
				DrawString(ModelStr);

				TextFont(systemFont);
				TextSize(0);
			end
		else begin
				LabelStr := 'No Video Digitizers are installed.';
				DrawString(LabelStr);
			end;
	end;  {WriteDigitizerInfo }


	procedure ShowVDigitizerInfo;
		var
			CurrentVDigitizer: VDHandle;
			infoDLOG: DialogPtr;
			item: integer;
			oldPort: GrafPtr;
	begin
		GetPort(oldPort);

		{ Open a dialog box and fill it in using the info from the VDigitizer. }
		infoDLOG := DSGetNewDialog(13003, nil, pointer(-1));
		SetPort(infoDLOG);

		CurrentVDigitizer := GetActiveVDigitizer;
		WriteDigitizerInfo(CurrentVDigitizer);
		OutlineButton(infoDLOG, ok, 16);

		repeat
			ModalDialog(nil, item);
		until (item = ok);

		DisposeDialog(infoDLOG);
		SetPort(oldPort);
	end;


	procedure DoVideoControl (item: integer);
		var
			i: integer;
			OutOfRange, WasDigitizing, hasCtrl: boolean;
			ioffset, igain, inc, count: integer;
			minGain, maxGain, rgain, minOffset, maxOffset, roffset, rinc: Real;
			VDigHandle, CurrentVDigitizer: VDHandle;
			status: OSErr;
			nChannels: Integer;
			itemType: integer;
			itemHandle: handle;
			itemRect: Rect;
	begin
		InitCursor;
		CurrentVDigitizer := GetActiveVDigitizer;

		{  Process a 'Select a Digitizer' button hit }
		if (item >= VDChoice1ID) and (item <= VDChoice3ID) then begin
				if (DigitizerSel[item - VDChoice1ID] <> nil) then begin
						WasDigitizing := digitizing;
						StopDigitizing;
						for i := 0 to 2 do begin
								if (item = VDChoice1ID + i) and (DigitizerSel[i] <> nil) then begin
										SetControlValue(DigitizerSel[i], 1);
										VDigHandle := GetNthVDigitizer(i);
										if VDigHandle <> nil then begin
											{ If there is a camera window, select and close it (to free locked memory). }
												if (VDigitizerInfo <> nil) then begin
														if (info^.PictureType <> VDigitizerType) then
															SelectWindow(VDigitizerInfo^.wptr);
														status := CloseAWindow(VDigitizerInfo^.wptr);
													end;

												CurrentVDigitizer := VDigHandle;
												status := SetVDigitizer(VDigHandle);
												vdGlobalSettings.vdBoardIndex := i + 1;
												GetVDGlobalSettings;

												HLock(Handle(VDigHandle));
												RefreshVideoControl;
												Hunlock(Handle(VDigHandle));

												if WasDigitizing then
													StartDigitizing;
											end;  { if VDigHandle <> nil }
									end  { if (item = VDChoice1ID + i) and (DigitizerSel[i] <> nil) }
								else if DigitizerSel[i] <> nil then
									SetControlValue(DigitizerSel[i], 0);
							end;  { for i := 0 to 2 }
					end;  { if (DigitizerSel[item-VDChoice1ID] <> nil) }
			end  { if (item >= VDChoice1ID) and (item <= VDChoice3ID) }

		else if item = GetVDInfoID then begin
				WasDigitizing := digitizing;
				StopDigitizing;
				ShowVDigitizerInfo;
				if WasDigitizing then
					StartDigitizing;
			end

		else if item = LoadInputLUTID then begin
				WasDigitizing := digitizing;
				StopDigitizing;
				if CurrentVDigitizer <> nil then begin
						DoLoadLUTDlog;
					end;
				if WasDigitizing then
					StartDigitizing;
			end

		else if (item >= FirstChannelID) and (item <= LastChannelID) then begin
				WasDigitizing := digitizing;
				StopDigitizing;
				if CurrentVDigitizer <> nil then begin
						VideoChannel := item - FirstChannelID + 1;
						status := GetVDigitizerNumChannels(nil, nChannels);
						ShowVDChannel(VideoChannel, nChannels);
						status := SetVDigitizerSrc(VideoChannel);
					end;
				if WasDigitizing then
					StartDigitizing;
			end

		else if item = HighlightID then begin
				HighlightSaturatedPixels := not HighlightSaturatedPixels;
				if VideoControl <> nil then
					SetDlogItem(VideoControl, HighlightID, ord(HighlightSaturatedPixels));
				if digitizing then begin
						if HighlightSaturatedPixels then
							HighlightPixels
						else
							UnHighlightPixels;
					end;
			end

		else if item = OscillatingID then begin
				OscillatingMovies := not OscillatingMovies;
				if VideoControl <> nil then
					SetDlogItem(VideoControl, OscillatingID, ord(OscillatingMovies));
			end

		else if item = BlindID then begin
				BlindMovieCapture := not BlindMovieCapture;
				if VideoControl <> nil then
					SetDlogItem(VideoControl, BlindID, ord(BlindMovieCapture));
			end

			{  Handle the external trigger checkbox}
		else if item = TriggerID then begin
				if CurrentVDigitizer <> nil then begin
						WasDigitizing := digitizing;
						StopDigitizing;
						case gExtTrigger of
							vdSource: 
								gExtTrigger := vdExternalStart;
							vdExternalStart: 
								gExtTrigger := vdSource;
							vdExternalStop: 
								gExtTrigger := vdExternalStartStop;
							vdExternalStartStop: 
								gExtTrigger := vdExternalStop;
						end;
						if VideoControl <> nil then
							if gExtTrigger = vdExternalStart then
								SetDlogItem(VideoControl, TriggerID, 1)
							else
								SetDlogItem(VideoControl, TriggerID, 0);
						if WasDigitizing then
							StartDigitizing;
					end;
			end

			{  Handle the "Use DMA for Display" checkbox}
		else if item = UseDMADisplayID then begin
				if CurrentVDigitizer <> nil then begin
						WasDigitizing := digitizing;
						StopDigitizing;
						UseDMADisplay := not UseDMADisplay;
						if UseDMADisplay then begin
								status := SetVDigitizerControlBits(0);
								if VideoControl <> nil then
									SetDlogItem(VideoControl, UseDMADisplayID, 0);
							end
						else begin
								status := SetVDigitizerControlBits(vdFcBDMAOut);
								if VideoControl <> nil then
									SetDlogItem(VideoControl, UseDMADisplayID, 1);
							end;
						if WasDigitizing then
							StartDigitizing;
					end;
			end

				{  Process the Set Mode Button  }
		else if (item = SetModeID) then begin
				if CurrentVDigitizer <> nil then begin
						WasDigitizing := digitizing;
						StopDigitizing;
						HLock(Handle(CurrentVDigitizer));
						if CurrentVDigitizer^^.vdModeInfo.vdMPListHdl <> nil then
							if CurrentVDigitizer^^.vdModeInfo.vdMPListHdl^^.vdMPNParams = 1 then
								DoCohuModalDlog
							else
								DoModalParamDlog
						else
							DoSetModeDlog;
						HUnlock(Handle(CurrentVDigitizer));
						if WasDigitizing then
							StartDigitizing;
					end;
			end

		{  Process the Configure Monitor button  }
		else if (item = ConfigureMonitorID) then begin
				if CurrentVDigitizer <> nil then begin
						WasDigitizing := digitizing;
						StopDigitizing;
						status := TestVDigitizerFeature(nil, vdFeBMultipleCameras, hasCtrl);
						if hasCtrl then begin
								{ If there is a camera window, select and close it (to free sized memory). }
								if (VDigitizerInfo <> nil) then begin
										if (info^.PictureType <> VDigitizerType) then
											SelectWindow(VDigitizerInfo^.wptr);
										status := CloseAWindow(VDigitizerInfo^.wptr);
									end;
								ConfigureCameraInfo;
							end
						else begin
								ConfigureMonitor;
								MaxDMADigWidth := GetMaxDMAWidth;
							end;
						if WasDigitizing then
							StartDigitizing;
					end;
			end

		else if (item >= OffsetUpID) and (item <= GainDownID) then begin
				if CurrentVDigitizer <> nil then begin
						status := GetVDigitizerGainMinMax(minGain, maxGain);
						status := GetVDigitizerGain(rgain);
						status := GetVDigitizerOffsetMinMax(minOffset, maxOffset);
						status := GetVDigitizerOffset(roffset);
						if status = noErr then begin
								inc := 1;
								count := 0;
								repeat
									count := count + 1;
									if count > 2 then
										inc := 2;
									if count > 4 then
										inc := 5;
									if count > 8 then
										inc := 10;
									status := TestVDigitizerFeature(nil, vdFeBMultipleCameras, hasCtrl);
									if not hasCtrl then begin
										rinc := inc * 0.003921; { * 0.01; }
										case item of
											OffsetUpID:  begin
													roffset := roffset + (rinc * (maxOffset - minOffset));
												end;
											OffsetDownID:  begin
													roffset := roffset - (rinc * (maxOffset - minOffset));
												end;
											GainUpID:  begin
													rgain := rgain + (rinc * (maxGain - minGain));
												end;
											GainDownID:  begin
													rgain := rgain - (rinc * (maxGain - minGain));
												end;
										end; {case}
									 end
									else begin
										case item of
											OffsetUpID:  begin
													rinc := inc * 0.00245;  { (10 * 0.5/2048) }
													roffset := roffset + rinc;
													if (roffset > maxOffset) then  roffset := maxOffset;
												end;
											OffsetDownID:  begin
													rinc := inc * 0.00245;  { (10 * 0.5/2048) }
													roffset := roffset - rinc;
													if (roffset < minOffset) then  roffset := minOffset;
												end;
											GainUpID:  begin
													if (rgain < 1.0) then
															rinc := inc * 0.165  { (min increment) }
													else if (rgain < 2.0) then
															rinc := inc * 0.33   { (min increment) }
													else if (rgain < 4.0) then
															rinc := inc * 0.66   { (min increment) }
													else
															rinc := inc * 1.33;  { (min increment) }
													rgain := rgain + rinc;
													if (rgain > maxGain) then  rgain := maxGain;
												end;
											GainDownID:  begin
													if (rgain < 1.0) then
															rinc := inc * 0.165  { (min increment) }
													else if (rgain < 2.0) then
															rinc := inc * 0.33   { (min increment) }
													else if (rgain < 4.0) then
															rinc := inc * 0.66   { (min increment) }
													else
															rinc := inc * 1.33;  { (min increment) }
													rgain := rgain - rinc;
													if (rgain < minGain) then  rgain := minGain;
												end;
										end; {case}
									 end;
									status := SetVDigitizerGain(rgain);
									status := SetVDigitizerOffset(roffset);
									ShowOffsetAndGain;
									if ContinuousHistogram then begin
											ShowContinuousHistogram;
											DrawHistogram;
										end;
									wait(5);
								until not button;
							end;
					end
				else begin
						beep;
					end;
			end

		else if item = ResetID then begin
				if CurrentVDigitizer <> nil then begin
						rgain := 1.0;
						roffset := 0.0;
						status := SetVDigitizerGain(rgain);
						status := SetVDigitizerOffset(roffset);
						ShowOffsetAndGain;
					end;
			end

		else if item = StartCapturingID then begin
				if CurrentVDigitizer <> nil then begin
						StartDigitizing;
						exit(DoVideoControl);
					end;
			end;

		if VideoControl <> nil then begin
				SelectWindow(VideoControl);
{InvalRect(CGrafPtr(VideoControl)^.portRect);}
				RefreshVideoControl;
			end;
	end;


procedure CorrectShadingOfLine (PicPtr, BFPtr: ptr; width, BFMean: integer);
{$IFC PowerPC}
VAR
  PicLine,BFLine:LinePtr;
  i,value:LongInt;
BEGIN
  PicLine:=LinePtr(PicPtr);
  BFLine:=LinePtr(BFPtr);
  FOR i:=0 TO width-1 DO BEGIN
    value:=PicLine^[i];
    value:=255-value;
    value:=(value * BFMean + (BFLine^[i] div 2)) DIV BFLine^[i];
    IF value>254 THEN value:=254;
    IF value<1 THEN value:=1;
    PicLine^[i]:=255-value;
  END;
END;
{$ELSEC}
  {a0=data pointer}
  {a1=blank field data pointer}
  {d0=count}
  {d1=pixel value}
  {d2=blank field pixel value}
  {d3=blank field mean}
  {d4=temp}
  {d5=max pixel value(245)}
  {d6=min pixel value(1)}
	inline
		$4E56, $0000, {   link	a6,#0}
		$48E7, $FEC0, {   movem.l	a0-a1/d0-d6,-(sp)}
		$206E, $000C, {   move.l	12(a6),a0}
		$226E, $0008, {   move.l	8(a6),a1}
		$4280,       {   clr.l	d0}
		$302E, $0006, {   move.w	6(a6),d0}
		$362E, $0004, {   move.w	4(a6),d3}
		$2A3C, $0000, $00FE, {   move.l	#254,d5}
		$2C3C, $0000, $0001, {   move.l	#1,d6}
		$5380,       {   subq.l	#1,d0}
		$4281,       {   clr.l	d1}
		$4282,       {   clr.l	d2}
		$1210,       {L1	move.b	(a0),d1}
		$1419,       {   move.b	(a1)+,d2}
		$4601,       {   not.b	d1}
		$C2C3,       {   mulu.w	d3,d1}
		$2802,       {   move.l	d2,d4}
		$E244,       {   asr.w	#1,d4}
		$D284,       {   add.l	d4,d1}
{**A (3) }
		$4A82,       {   tst.l d2 (to prevent zero divide) }
		$6606,       {   bne.s	L1a}
		$0682, $0000, $0001,     {   addi.l	#1,d2}
		$82C2,       {L1a  divu.w	d2,d1}
		$B245,       {   cmp.w	d5,d1}
		$6F02,       {   ble.s	L2}
		$3205,       {   move.w	d5,d1}
		$B246,       {L2	cmp.w	d6,d1}
		$6C02,       {   bge.s	L3}
		$3206,       {   move.w	d6,d1}
		$4601,       {L3	not.b	d1}
		$10C1,       {   move.b	d1,(a0)+}
		$51C8, $FFD4, {   dbra	d0,L1}
		$4CDF, $037F, {   movem.l	(sp)+,a0-a1/d0-d6}
		$4E5E,       {   unlk	a6}
		$DEFC, $000C; {   add.w	#12,sp}
{$ENDC}


	procedure CorrectShading;
		var
			i, tag, width: integer;
			offset, NextUpdate: LongInt;
			p1, p2: ptr;
			str: str255;
			MaskRect:rect;
	begin
		with info^ do begin
				if ImageSize <> BlankFieldInfo^.ImageSize then begin
						beep;
						exit(CorrectShading);
					end;
				ShowWatch;
				tag:=0;
				NextUpdate:=TickCount+6;
				width:=PicRect.right;
				p1 := PicBaseAddr;
				p2 := BlankFieldInfo^.PicBaseAddr;
				for i := 1 to nLines do begin
						CorrectShadingOfLine(p1, p2, PixelsPerLine, BlankFieldMean);
						p1 := ptr(ord4(p1) + info^.BytesPerRow);
						p2 := ptr(ord4(p2) + BlankFieldInfo^.BytesPerRow);
					if TickCount>=NextUpdate then begin
							SetRect(MaskRect, 0, tag, width, i);
							UpdateScreen(MaskRect);
							tag:=i;
							NextUpdate:=TickCount+6;
						end;
					end;
				SetRect(MaskRect, 0, tag, width, nLines);
				UpdateScreen(MaskRect);
				str := title;
				if SpatiallyCalibrated then
					str := concat(str, chr($13)); {Black Diamond}
				if fit <> uncalibrated then
					str := concat(str, '');
				if wptr <> nil then
					SetWTitle(wptr, concat(str, ' (Corrected)'));
			end;
	end;


	procedure GrabOffscreenFrame;
		var
			buffer, top, left: integer;
			status: OSErr;
	begin
		with Info^ do begin
				HideCursor;
				buffer := -1;
				HLock(handle(osPort^.portPixMap));
				if roiShowing then begin
						top := VDigitizerInfo^.RoiRect.top;
						left := VDigitizerInfo^.RoiRect.left;
						status := ReadVDigitizerFrmeBuf(buffer, top, left, osPort^.portPixMap, @RoiRect)
					end
				else if StackInfo <> nil then begin
						top := VDigitizerInfo^.RoiRect.top;
						left := VDigitizerInfo^.RoiRect.left;
						status := ReadVDigitizerFrmeBuf(buffer, top, left, osPort^.portPixMap, nil)
					end
				else
					status := ReadVDigitizerFrmeBuf(buffer, wrect.top, wrect.left, osPort^.portPixMap, nil);
				HUnlock(handle(osPort^.portPixMap));
				ShowCursor;
			end;
	end;


	procedure CopyCameraFrameOffscreen;
		var
			dst: ptr;
			line, i: integer;
			lineBuffer: packed array[0..2048] of UnsignedByte;
			tPort: GrafPtr;
			sRect, dRect: Rect;
			wwidth, wheight, pwidth, pheight: Integer;
			windowSameSizeAsOffscreen: Boolean;
	begin
		with Info^ do begin
				wwidth := wrect.right - wrect.left;
				wheight := wrect.bottom - wrect.top;
				pwidth := PicRect.right - PicRect.left;
				pheight := PicRect.bottom - PicRect.top;
				windowSameSizeAsOffscreen := (wwidth = pwidth) and (wheight = pheight);
				if not windowSameSizeAsOffscreen and not RoiShowing then begin
			{ Fill the offscreen buffer with a medium gray so un-grabbed areas will look good for scrolling. }
						for i := 0 to 2048 do
							lineBuffer[i] := 200;
						dst := ptr(LongInt(PicBaseAddr));
						for line := 1 to nlines do begin
								BlockMove(@lineBuffer, dst, PixelsPerLine);
								dst := ptr(ord4(dst) + BytesPerRow);
							end;
					end;

		{ Copy the image data into the offscreen buffer. }
				getPort(tPort);
				SetPort(wptr);
				hlock(handle(osPort^.portPixMap));
				hlock(handle(CGrafPort(wptr^).PortPixMap));
				if not roiShowing then begin
						sRect := CGrafPort(wptr^).PortRect;
						if windowSameSizeAsOffscreen then
							dRect := PicRect
						else
							dRect := SrcRect;
					end
				else begin
						sRect := RoiRect;
						dRect := RoiRect;
					end;
				CopyBits(BitMapHandle(CGrafPort(wptr^).PortPixMap)^^, BitMapHandle(osPort^.portPixMap)^^, sRect, dRect, SrcCopy, nil);
				hunlock(handle(osPort^.portPixMap));
				hunlock(handle(CGrafPort(wptr^).PortPixMap));
				SetPort(tPort);
			end;
	end;


	procedure CaptureFrameOffscreen;
		var
			status: OSErr;
			nBuffers: Integer;
	begin
		status := GetVDigitizerNumBuffers(nil, nBuffers);
		if nBuffers > 0 then begin
				GrabOffscreenFrame;
			end
		else begin
				CopyCameraFrameOffscreen;
			end;
	end;


{-- procedure SetupCaptureWindow - Prepares the capture window for digitizing.  If a	}
{-- camera window of the correct type and size is open, it is used for display; else, 			}
{-- a new window is created using info from the VDigitizer.					}

	function SetupCaptureWindow: boolean;
		var
			width, height: integer;
			NewRect, deskRect, aRect, fbRect: Rect;
			MonitorSize, DigModeSize, DigFBSize, DigLiveSize: Point;
			status: OSErr;
			lclVDMInfoPtr: VDMInfoPtr;
			lclMode: integer;
			needNewCamera: boolean;
			edgesRect: Rect;
	begin
		{  Initialize the completion status.	}
		SetupCaptureWindow := false;

		{  Get the mode information		}
		lclVDMInfoPtr := VDMInfoPtr(NewPtr(SizeOf(VDModalInfo)));
		if (lclVDMInfoPtr = nil) then begin
				PutMessage('Out of memory, could not setup capture window');
				Exit(SetupCaptureWindow);
			end;

		status := GetVDigitizerMode(lclMode);
		status := GetVDigitizerModeInfo(lclVDMInfoPtr, lclMode);

		{	 Get the sizes for the different windows }
		deskRect := DSGetDesk;
		MonitorSize.h := deskRect.right - deskRect.left;
		MonitorSize.v := deskRect.bottom - deskRect.top;
		status := GetVDigitizerFBSize(nil, 1, DigFBSize);
		status := GetVDigitizerDisplaySize(nil, DigLiveSize);
		status := GetVDigitizerVideoSize(nil, DigModeSize);

		{  Release the allocated memory  }
		DisposePtr(ptr(lclVDMInfoPtr));

		{  Initialize the completion status.	}
		SetupCaptureWindow := true;

		{ If there is a digitizer window, but it is not selected, select and use it. }
		if (VDigitizerInfo <> nil) and (info^.PictureType <> VDigitizerType) then begin
				SelectWindow(VDigitizerInfo^.wptr);
				info := VDigitizerInfo;
			end;

		{ Determine the size for the digitizer window based on digitizer limits. }
		vdSWidth := DigModeSize.h;
		vdSHeight := DigModeSize.v;

		{ If the digitizer has edges, adjust for them now. }
		status := GetVDigitizerCameraEdges(edgesRect);
		if status = noErr then begin
				vdSWidth := vdSWidth - (edgesRect.left + edgesRect.right);
				vdSHeight := vdSHeight - (edgesRect.top + edgesRect.bottom);
			end;

{  Check to see if the window is big enough  }
		needNewCamera := false;
		if info <> nil then begin
				with info^ do begin
						if PictureType = VDigitizerType then
							if (osPort^.portRect.bottom <> vdSHeight) or (osPort^.portRect.right <> vdSWidth) then
								needNewCamera := true;
					end;  {with info^ do}
			end;  {if info <> nil}
		if needNewCamera = true then
			status := CloseAWindow(Info^.wptr);

	{ If the window is not the right size or does not exist, create a new digitizer window. }
		with info^ do
			if (PictureType <> VDigitizerType) or (PixelsPerLine <> vdSWidth) or (nlines <> vdSHeight) then begin
					if NewPicWindow('Camera', vdSWidth, vdSHeight) = true then begin
							info^.PictureType := VDigitizerType;
							VDigitizerInfo := info;
							SetRect(fbRect, 0, 0, vdSWidth, vdSHeight);
							if not EqualRect(fbRect, info^.SrcRect) then {Center Frame}
								with info^.SrcRect do begin
										width := right - left;
										height := bottom - top;
										if not BlindMovieCapture then begin
												left := (fbRect.right - width) div 2;
												top := (fbRect.bottom - height) div 2;
											end
										else begin
												left := fbRect.left;
												top := fbRect.top;
											end;
										right := left + width;
										bottom := top + height;
									end;  {with SrcRect do begin}
						end  {if NewPicWindow('Camera'}
					else
						SetupCaptureWindow := false;
				end;  {if (PictureType <> VDigitizerType}

		with info^ do begin
				{ If the window is scaled, turn off scaling for digitizer window. }
{**if (ScaleToFitWindow = true) then }
{**ScaleToFit;}

				{ Adjust the digitizer window position/size to accommodate any hardware/software	}
				{     boundary restrictions. 																																														}
				aRect := wRect;
				aRect.right := aRect.left + vdCWidth;
				if AdjustVDigitizerWindow(wptr, aRect) = noErr then begin
						GetWindowRect(wptr, NewRect);
						height := NewRect.bottom - NewRect.top;
						width := NewRect.right - NewRect.left;
						wrect.bottom := wrect.top + height;
						wrect.right := wrect.left + width;

						{ Adjust the position/size of the capture rect in the offscreen GrafPort. }
						if AdjustVDigitizerGrabRect(SrcRect) <> noErr then
							SetupCaptureWindow := false;
					end  {if AdjustVDigitizerWindow}
				else
					SetupCaptureWindow := false;
			end;  {with info^ do begin}
	end;


	{  Adjust the display rectangle based on the current size of the window rectangle}
	{  and the size of the desktop.  Assumes that the window has already been adjusted}
	{  by AdjustVDigitizerWindow and AdjustVDigitizerGrabRect and that the global }
	{  info ^ points to the correct digitizer window}
	procedure AdjustDisplayRect (var theDisplayRect: rect);
		const
			borderSize = 2;
		var
			theDeskRect: rect;
			theWindowRect: rect;
	begin
		{  Adjust the display size based on the window  }
		GetWindowRect(info^.wptr, theWindowRect);
		theDisplayRect := theWindowRect;
		if theDisplayRect.left <> 0 then begin
				theDisplayRect.right := theDisplayRect.right - theDisplayRect.left;
				theDisplayRect.left := 0;
			end;
		if theWindowRect.left < 0 then
			theDisplayRect.left := borderSize - theWindowRect.left;
		if theDisplayRect.top <> 0 then begin
				theDisplayRect.bottom := theDisplayRect.bottom - theDisplayRect.top;
				theDisplayRect.top := 0;
			end;

		{  Adjust the display rect based on the desk rect  }
		theDeskRect := DSGetDesk;
		if theWindowRect.top + theDisplayRect.bottom > theDeskRect.bottom - borderSize then
			theDisplayRect.bottom := theDeskRect.bottom - theWindowRect.top - borderSize;
		if theDisplayRect.bottom < 0 then
			theDisplayRect.bottom := 1;
		if theWindowRect.left + theDisplayRect.right > theDeskRect.right - borderSize then
			theDisplayRect.right := theDeskRect.right - theWindowRect.left - borderSize;
	end;


{-- procedure StartDigitizing - If not already digitizing and displaying a live image,		}
{-- this routine enables the currently selected digitizer to start digitizing and 						}
{-- displaying a live image from the currently selected video input channel.  If a					}
{-- camera window is open, it is used for display; else, a new window is created.					}
{-- If already digitizing, this function just calls StopDigitizing to stop the live image	}
{-- display.																					}

	procedure StartDigitizing;
		const
			shortTimeout = 15 * 60;
			longTimeout = 5 * 60 * 60;
		type
			extraPRec = record
					paramsPtr: Ptr;
					scaleResult: Integer;
					scaleMin: LongInt;
					scaleMax: LongInt;
				end;
		var
			frames: integer;
			extraParams: Ptr;
			extraParamsRec: extraPRec;
			RefImagePM: PixMapHandle;
			hasBkgImage: boolean;
			lclTrigger: integer;
			status: OSErr;
			lclDispRect: Rect;
			timeoutTicks: Integer;
			hasFeature, hasALU, okToProceed: Boolean;
			oldPort: GrafPtr;
			lclMode: integer;
			DigFBSize: Point;
			fbRect, edgesRect: Rect;
		procedure AcqProblem (msgStr: Str255);
		begin
			Digitizing := false;
			SetWTitle(info^.wptr, 'Camera');
			PutMessage(msgStr);
		end;
	begin

		{ If already digitizing, this function is really 'Stop Digitizing'. }
		if Digitizing or DigitizingInterrupted then begin
				StopDigitizing;
				SetMenuItemText(SpecialMenuH, StartItem, 'Start Capturing');
				if BlankFieldInfo <> nil then
					wait(5);
				FlushEvents(EveryEvent, 0); {In case user holds key down too long}
				exit(StartDigitizing)
			end;

		{ Make sure there is a digitizer in the system. }
		if ActvVDigitizer <> nil then begin
				if SetupCaptureWindow = true then begin

						{  Setup the window stuff	}
						GetPort(oldPort);
						SetPort(info^.wptr);
						SetWTitle(info^.wptr, 'Camera(Live)');
						Digitizing := true;

						if HighlightSaturatedPixels then
							HighlightPixels;

						{  Load the digitizer's lookup tables. }
{LoadInputLookupTable;}
{LoadOutputLookupTable;}

						{  Adjust the display rect as necessary}
						AdjustDisplayRect(lclDispRect);

						{  Is a background image available?  }
						hasBkgImage := false;
						if bkgImageInfo <> nil then
							hasBkgImage := true;

						{ Check to see if the option key is down for external trigger}
						if OptionKeyDown then
							lclTrigger := vdExternalStart
						else
							lclTrigger := gExtTrigger;

						timeoutTicks := longTimeout;
						if lclTrigger = vdSource then begin
								status := TestVDigitizerFeature(nil, vdFeBALU, hasFeature);
								if hasFeature then
									timeoutTicks := shortTimeout;
							end;
						status := SetVDigitizerTimeOut(timeoutTicks);

						{  Start the acquisition	}
						case gvdOperation of
							vdNone:
								{  We want to do a live raw sample of video  }
								begin
									frames := 0;
									with info^ do begin
											if not ScaleToFitWindow then
												status := CaptureVDigitizerFrames(frames, vdNone, lclTrigger, nil, nil, SrcRect, nil, SrcRect, wptr, lclDispRect)
											else begin
													status := GetVDigitizerFBSize(nil, 1, DigFBSize);
													{ If the digitizer has edges, accommodate them. }
													status := GetVDigitizerCameraEdges(edgesRect);
													if status = noErr then begin
															fbRect.left := 0;
															fbRect.right := DigFBSize.h - (edgesRect.left + edgesRect.right);
															fbRect.top := 0;
															fbRect.bottom := DigFBSize.v - (edgesRect.top + edgesRect.bottom);
														end
													else
														SetRect(fbRect, 0, 0, DigFBSize.h, DigFBSize.v);
													status := CaptureVDigitizerFrames(frames, vdNone, lclTrigger, nil, nil, fbRect, nil, SrcRect, wptr, lclDispRect);
												end;
											if status = noErr then begin
													BinaryPic := false;
													if lclTrigger <> vdSource then
														StopDigitizing;
												end  { if CaptureVDigitizerFrames(}
											else
												PutMessage('Had a problem with the acquisition.');
										end;  { with info^ do  }
								end;  { case of vdNone  }

							vdArithAvg:
								{  we want to do an average of <FramesToAverage> number of frames  }
								begin
									frames := FramesToAverage;
									okToProceed := true;
									status := TestVDigitizerFeature(nil, vdFeBALU, hasALU);
									if not hasALU then begin
											if not AllocateAccumBuffer then begin
													AcqProblem('Had a problem with the Arithmetic Average operation.');
													okToProceed := false;
												end;
										end;
									if okToProceed then begin
											extraParamsRec.paramsPtr := Ptr(@gBigFBPtr);
											if gScaleDigResults then
												extraParamsRec.scaleResult := 1
											else
												extraParamsRec.scaleResult := 0;
											ShowWatch;
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdArithAvg, lclTrigger, nil, Ptr(@extraParamsRec), SrcRect, osPort^.portPixMap, SrcRect, wptr, lclDispRect);
													if status = noErr then
														StopDigitizing
													else
														AcqProblem('Had a problem with the Arithmetic Average operation.');
												end;  { with info^ do  }
										end;  { if okToProceed  }
								end;  { vdArithAvg:  }

							vdGeomAvg:
								{  we want to do a geometric average with a certain weighting factor  }
								begin
									frames := FramesToAverage;
									extraParamsRec.paramsPtr := Ptr(@gGeoAveWt);
									extraParamsRec.scaleResult := 0;
									if frames <> 0 then
										ShowWatch;
									with info^ do begin
											status := CaptureVDigitizerFrames(frames, vdGeomAvg, lclTrigger, nil, Ptr(@extraParamsRec), SrcRect, nil, SrcRect, wptr, lclDispRect);
											if status = noErr then begin
													if frames <> 0 then
														StopDigitizing
													else
														BinaryPic := false;
												end
											else
												AcqProblem('Had a problem with the Geometric Average operation.');
										end;  { with info^ do  }
								end;  { vdGeomAvg begin }

							vdIntegrate:
								{  we want to integrate for <FramesToAverage> number of frames  }
								begin
									frames := FramesToAverage;
									okToProceed := true;
									status := TestVDigitizerFeature(nil, vdFeBALU, hasALU);
									if not hasALU then begin
											if not AllocateAccumBuffer then begin
													AcqProblem('Had a problem with the Arithmetic Average operation.');
													okToProceed := false;
												end;
										end;
									if okToProceed then begin
											extraParamsRec.paramsPtr := Ptr(@gBigFBPtr);
											extraParamsRec.scaleResult := ord(gIntegrationScalingType);
											extraParamsRec.scaleMin := gIntegrationMin;
											extraParamsRec.scaleMax := gIntegrationMax;
											if frames <> 0 then
												ShowWatch;
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdIntegrate, lclTrigger, nil, Ptr(@extraParamsRec), SrcRect, osPort^.portPixMap, SrcRect, wptr, lclDispRect);
													if status = noErr then begin
															if frames <> 0 then
																StopDigitizing
															else
																BinaryPic := false;
														end  { if CaptureVDigitizerFrames(}
													else
														AcqProblem('Had a problem with the Integration operation.');
												end;  { with info^ do  }
										end;  { if okToProceed  }
								end;  { vdIntegrate begin }

							vdSubtractLive:
								{  we want to subtract the background from the incoming picture  }
								begin
									frames := 0;
									if hasBkgImage then begin
											HLock(handle(BkgImageInfo^.osPort^.portPixMap));
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdSubtractLive, lclTrigger, BkgImageInfo^.osPort^.portPixMap, nil, SrcRect, nil, SrcRect, wptr, lclDispRect);
													if status = noErr then begin
															BinaryPic := false;
															if lclTrigger <> vdSource then
																StopDigitizing;
														end  { if status = noErr }
													else
														AcqProblem('Had a problem with the Subtract operation.');
												end;  { with info^ do  }
											HUnlock(handle(BkgImageInfo^.osPort^.portPixMap));
										end    {if hasBkgImage}
									else
										AcqProblem('No Background Image.');
								end;  { vdSubtractLive begin }

							vdMultiplyLive:
								{  we want to multiply the background with the incoming picture  }
								begin
									frames := 0;
									if hasBkgImage then begin
											HLock(handle(BkgImageInfo^.osPort^.portPixMap));
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdMultiplyLive, lclTrigger, BkgImageInfo^.osPort^.portPixMap, nil, SrcRect, nil, SrcRect, wptr, lclDispRect);
													if status = noErr then begin
															BinaryPic := false;
															if lclTrigger <> vdSource then
																StopDigitizing;
														end
													else
														AcqProblem('Had a problem with the Subtract operation.');
												end;  { with info^ do  }
											HUnlock(handle(BkgImageInfo^.osPort^.portPixMap));
										end    {if hasBkgImage}
									else
										AcqProblem('No Background Image.');
								end;  { vdMultiplyLive begin }

							vdBgdSubAvg:
								{  we want to average the difference between the background and the incoming picture  }
								begin
									frames := FramesToAverage;
									extraParamsRec.paramsPtr := nil;
									if gScaleDigResults then
										extraParamsRec.scaleResult := 1
									else
										extraParamsRec.scaleResult := 0;
									ShowWatch;
									if hasBkgImage then begin
											HLock(handle(BkgImageInfo^.osPort^.portPixMap));
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdBgdSubAvg, lclTrigger, BkgImageInfo^.osPort^.portPixMap, Ptr(@extraParamsRec), SrcRect, nil, SrcRect, wptr, lclDispRect);
													if status = noErr then begin
															StopDigitizing;
														end
													else
														AcqProblem('Had a problem with the Background Subtract operation.');
												end;  { with info^ do  }
											HUnlock(handle(BkgImageInfo^.osPort^.portPixMap));
										end    {if hasBkgImage}
									else
										AcqProblem('No Background Image.');
								end;  { vdBgdSubAvg begin }

							vdBgdSubGeom:
								{  we want to average the difference between the background and the incoming picture  }
								begin
									frames := FramesToAverage;
									if frames <> 0 then
										ShowWatch;
									if hasBkgImage then begin
											HLock(handle(BkgImageInfo^.osPort^.portPixMap));
											extraParamsRec.paramsPtr := Ptr(@gGeoAveWt);
											extraParamsRec.scaleResult := 0;
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdBgdSubGeom, lclTrigger, BkgImageInfo^.osPort^.portPixMap, Ptr(@extraParamsRec), SrcRect, nil, SrcRect, wptr, lclDispRect);
													if status = noErr then begin
															if frames <> 0 then
																StopDigitizing
															else
																BinaryPic := false;
														end
													else
														AcqProblem('Had a problem with the Background Subtract operation.');
												end;  { with info^ do  }
											HUnlock(handle(BkgImageInfo^.osPort^.portPixMap));
										end    {if hasBkgImage}
									else
										AcqProblem('No Background Image.');
								end;  { vdBgdSubGeom begin }

							vdBgdSubIntegrate:
								{  we want to integrate the difference between the background and the incoming picture  }
								begin
									frames := FramesToAverage;
									extraParamsRec.paramsPtr := nil;
									extraParamsRec.scaleResult := ord(gIntegrationScalingType);
									extraParamsRec.scaleMin := gIntegrationMin;
									extraParamsRec.scaleMax := gIntegrationMax;
									if frames <> 0 then
										ShowWatch;
									if hasBkgImage then begin
											HLock(handle(BkgImageInfo^.osPort^.portPixMap));
											with info^ do begin
													status := CaptureVDigitizerFrames(frames, vdBgdSubIntegrate, lclTrigger, BkgImageInfo^.osPort^.portPixMap, Ptr(@extraParamsRec), SrcRect, nil, SrcRect, wptr, lclDispRect);
													if status = noErr then begin
															if frames <> 0 then
																StopDigitizing
															else
																BinaryPic := false;
														end
													else
														AcqProblem('Had a problem with the Background Subtracted Integration operation.');
												end;  { with info^ do  }
											HUnlock(handle(BkgImageInfo^.osPort^.portPixMap));
										end    {if hasBkgImage}
									else
										AcqProblem('No Background Image.');
								end;  { vdBgdSubIntegrate begin }

							vdDoCustomFcn:
								{  we want to invoke a custom digitizer capture function  }
								{  NOTE:  Always use the background image if it's available  }
								begin
									frames := FramesToAverage;
									if frames <> 0 then
										ShowWatch;
									with info^ do begin
											if hasBkgImage = true then begin
													HLock(handle(BkgImageInfo^.osPort^.portPixMap));
													status := CaptureVDigitizerFrames(frames, vdCustomGrabOp, lclTrigger, BkgImageInfo^.osPort^.portPixMap, nil, SrcRect, nil, SrcRect, wptr, lclDispRect);
													HUnlock(handle(BkgImageInfo^.osPort^.portPixMap));
												end
											else
												status := CaptureVDigitizerFrames(frames, vdCustomGrabOp, lclTrigger, nil, nil, SrcRect, nil, SrcRect, wptr, lclDispRect);

											if status = noErr then begin
													if frames = 0 then begin
															BinaryPic := false;
														end
													else begin
															StopDigitizing;
														end;
												end
											else
												AcqProblem('Had a problem with the Custom Function operation.');
										end;  {with info^ do }
								end;  { vdDoCustomFcn begin }
						end;  {  case gvdOperation of  }
						SetPort(oldPort);
						if VideoControl <> nil then
							RefreshVideoControl;
					end
				else
					PutMessage('Had a problem setting up the windows');
			end
		else
			PutMessage('Digitizing requires a (supported) frame grabber card.');
	end;


	function Ave1ItemDlog (DlogNum: integer): boolean;
		const
			tAveNumFrm = 6;
			tScaleResult = 12;
		var
			AveDlgPtr: DialogPtr;
			item: integer;
			NumFrm: longint;
			Done: Boolean;
			itemText: Str255;
			saveResultsFlag: Boolean;
			oldPort: GrafPtr;
	begin

		{  Initialize some variables	}
		Ave1ItemDlog := false;
		Done := false;
		NumFrm := FramesToAverage;
		item := 0;
		GetPort(oldPort);

		{  Display the dialog, outline the button and select the desired text }
		AveDlgPtr := DSGetNewDialog(DlogNum, nil, pointer(-1));
		SetPort(AveDlgPtr);
		OutlineButton(AveDlgPtr, ok, 16);

		{  Show how many frames to average		}
		if ((DlogNum = rArithAve) or (DlogNum = rBkSubArAve)) and (NumFrm < 4) then
			NumFrm := 4;
		NumToString(NumFrm, itemText);
		SetDString(AveDlgPtr, tAveNumFrm, itemText);
		SelectDialogItemText(AveDlgPtr, tAveNumFrm, 0, gMaxInt);

		if gScaleDigResults then
			SetDlogItem(AveDlgPtr, tScaleResult, 1)
		else
			SetDlogItem(AveDlgPtr, tScaleResult, 0);
		saveResultsFlag := gScaleDigResults;

		{  Keep getting something until the user cancels or gives a valid number	}
		while (Done <> true) do begin
				ModalDialog(nil, item);

				if item = tScaleResult then begin
						saveResultsFlag := not saveResultsFlag;
						if saveResultsFlag then
							SetDlogItem(AveDlgPtr, tScaleResult, 1)
						else
							SetDlogItem(AveDlgPtr, tScaleResult, 0);
					end;

				if item = OK then begin
						NumFrm := GetDNum(AveDlgPtr, tAveNumFrm);

						{  If we have a good number, save it and end the dialog	}
						if (DlogNum = rArithAve) or (DlogNum = rBkSubArAve) then begin
								if (4 <= NumFrm) and (NumFrm <= 256) then begin
								{  Put the number of frames into a global variable somehow	}
										FramesToAverage := NumFrm;
										Ave1ItemDlog := true;
										gScaleDigResults := saveResultsFlag;
										Done := true;
									end;  { if (NumFrm ...)  }
							end
						else if (DlogNum = rIntegrate) or (DlogNum = rBkSubIntegrate) then begin
								if (0 <= NumFrm) and (NumFrm <= 256) then begin
								{  Put the number of frames into a global variable somehow	}
										FramesToAverage := NumFrm;
										Ave1ItemDlog := true;
										gScaleDigResults := saveResultsFlag;
										Done := true;
									end;  { if (NumFrm ...)  }
							end

						{  Otherwise, we have a bad number so try it again		}
						else begin
								SelectDialogItemText(AveDlgPtr, tAveNumFrm, 0, gMaxInt);
								SysBeep(1);
							end;		{ else begin }
					end;

				if item = Cancel then
					Done := true;
			end;						{  while (Done <> true)  }
		DisposeDialog(AveDlgPtr);
		SetPort(oldPort);
	end;


	function GeoWeightDlog (DlogNum: integer): boolean;
		const
			tGeoNumFrm = 6;
			tGeoWeight = 14;
		var
			GeoWtDlgPtr: DialogPtr;
			item: integer;
			WeightingFactor: LongReal;
			NumFrm: longint;
			Done: Boolean;
			itemText: Str255;
			oldPort: GrafPtr;
	begin

		{  Initialize some variables	}
		GeoWeightDlog := false;
		Done := false;
		WeightingFactor := gGeoAveWt;
		NumFrm := FramesToAverage;
		item := 0;
		GetPort(oldPort);

		{  Display the dialog and outline the OK button}
		GeoWtDlgPtr := DSGetNewDialog(DlogNum, nil, pointer(-1));
		SetPort(GeoWtDlgPtr);
		OutlineButton(GeoWtDlgPtr, ok, 16);

		{  Display the number of frames to average		}
		NumToString(NumFrm, itemText);
		SetDString(GeoWtDlgPtr, tGeoNumFrm, itemText);

		{  Display the weighting factor and select it		}
		itemText := StringOf(WeightingFactor : 5 : 4);
		SetDString(GeoWtDlgPtr, tGeoWeight, itemText);
		SelectDialogItemText(GeoWtDlgPtr, tGeoWeight, 0, gMaxInt);

		{  Keep getting something until the user cancels or gives a valid number	}
		while (Done <> true) do begin
				repeat
					ModalDialog(nil, item);
				until (item = OK) or (item = cancel);

				if item = OK then begin
						{  Get the weighting factor		}
						WeightingFactor := GetDReal(GeoWtDlgPtr, tGeoWeight);

						{  If we have a good number, save it and check the number of frames	}
						if (0 < WeightingFactor) and (WeightingFactor < 1.0) then begin

								{  Set up to average for a number of frames		}
								NumFrm := GetDNum(GeoWtDlgPtr, tGeoNumFrm);

								{  If we have a good number, save it and end the dialog	}
								if (0 <= NumFrm) and (NumFrm <= 256) then begin
										{  Put the number of frames into a global variable	}
										FramesToAverage := NumFrm;

										{  Put the weighting factor into a global variable	}
										gGeoAveWt := WeightingFactor;

										GeoWeightDlog := true;
										Done := true;
									end  { if (2 <= NumFrm)  }

										{  Otherwise, we have a bad number of frames so try it again		}
								else begin
										SelectDialogItemText(GeoWtDlgPtr, tGeoNumFrm, 0, gMaxInt);
										SysBeep(1);
									end;		{ else begin }
							end
						{  Otherwise, we have a bad weighting factor so try it again		}
						else begin
								SelectDialogItemText(GeoWtDlgPtr, tGeoWeight, 0, gMaxInt);
								SysBeep(1);
							end;		{ else begin }

					end;  { item = OK  }

				if item = Cancel then
					Done := true;
			end;						{  while (Done <> true)  }
		DisposeDialog(GeoWtDlgPtr);
		SetPort(oldPort);
	end;


	function IntegrationDlog (DlogNum: integer): boolean;
		const
			tIntegrateNumFrm = 5;
			tScaleNoneButton = 8;
			tScaleAutoButton = 9;
			tScaleFixedButton = 10;
			tScaleFixedMin = 12;
			tScaleFixedMax = 14;
		var
			IntegDlgPtr: DialogPtr;
			item: integer;
			NumFrm: longint;
			Done, FixedScaleOK: Boolean;
			itemText: Str255;
			saveResultsFlag: Boolean;
			saveNumFrames, saveIntegrationMin, saveIntegrationMax: longint;
			saveScaleOption: integer;
			oldPort: GrafPtr;
	begin

		{  Initialize some variables	}
		IntegrationDlog := false;
		Done := false;
		NumFrm := FramesToAverage;
		item := 0;
		GetPort(oldPort);

		{  Display the dialog, outline the button and select the desired text }
		IntegDlgPtr := DSGetNewDialog(DlogNum, nil, pointer(-1));
		SetPort(IntegDlgPtr);
		OutlineButton(IntegDlgPtr, ok, 16);

		{  Show how many frames to average		}
		if (NumFrm < 2) then
			NumFrm := 2;
		NumToString(NumFrm, itemText);
		SetDString(IntegDlgPtr, tIntegrateNumFrm, itemText);
		SelectDialogItemText(IntegDlgPtr, tIntegrateNumFrm, 0, gMaxInt);

		if (gIntegrationScalingType < IntegScaleNone) or (gIntegrationScalingType > IntegScaleFixed) then
			gIntegrationScalingType := IntegScaleNone;
		UpdateRadioGroup(IntegDlgPtr, tScaleNoneButton, tScaleNoneButton + ord(gIntegrationScalingType));
		if (gIntegrationMin < 0) then
			gIntegrationMin := 0;
		NumToString(gIntegrationMin, itemText);
		SetDString(IntegDlgPtr, tScaleFixedMin, itemText);
		if (gIntegrationMax > 65536) then
			gIntegrationMax := 65536;
		NumToString(gIntegrationMax, itemText);
		SetDString(IntegDlgPtr, tScaleFixedMax, itemText);

		saveNumFrames := NumFrm;
		saveScaleOption := ord(gIntegrationScalingType);
		saveIntegrationMin := gIntegrationMin;
		saveIntegrationMax := gIntegrationMax;

		{  Keep getting something until the user cancels or gives a valid number	}
		while (Done <> true) do begin
				ModalDialog(nil, item);

				if (item >= tScaleNoneButton) and (item <= tScaleFixedButton) then begin
						UpdateRadioGroup(IntegDlgPtr, tScaleNoneButton, item);
						gIntegrationScalingType := IntegrationScalingType(item - tScaleNoneButton);
					end;

				if item = OK then begin
						NumFrm := GetDNum(IntegDlgPtr, tIntegrateNumFrm);
						gIntegrationMin := GetDNum(IntegDlgPtr, tScaleFixedMin);
						gIntegrationMax := GetDNum(IntegDlgPtr, tScaleFixedMax);

						{  Make sure the integration range is valid if using fixed scaling	}
						if gIntegrationScalingType = IntegScaleFixed then begin
								if (gIntegrationMax > gIntegrationMin) then begin
										FixedScaleOK := true;
									end

						{  Otherwise, we have a bad number so try it again		}
								else begin
										FixedScaleOK := false;
										SelectDialogItemText(IntegDlgPtr, tScaleFixedMax, 0, gMaxInt);
										SysBeep(1);
									end;		{ else begin }
							end
						else
							FixedScaleOK := true;

						if FixedScaleOK then begin
								{  If we have a good number of frames, save it and end the dialog	}
								if (2 <= NumFrm) and (NumFrm <= 256) then begin
										{  Put the number of frames into a global variable	}
										FramesToAverage := NumFrm;
										IntegrationDlog := true;
										Done := true;
									end

								{  Otherwise, we have a bad number so try it again		}
								else begin
										SelectDialogItemText(IntegDlgPtr, tIntegrateNumFrm, 0, gMaxInt);
										SysBeep(1);
									end;		{ else begin }
							end;
					end;

				if item = Cancel then begin
						gIntegrationScalingType := IntegrationScalingType(saveScaleOption);
						gIntegrationMin := saveIntegrationMin;
						gIntegrationMax := saveIntegrationMax;
						Done := true;
					end;
			end;						{  while (Done <> true)  }
		DisposeDialog(IntegDlgPtr);
		SetPort(oldPort);
	end;


	function CustomALUDlog;  { :Boolean; }
		var
			status: OSErr;
			nFrames, nTicks: LongInt;
	begin
		status := DoVDigitizerCustomFunction(0);
		if status = noErr then begin
				CustomALUDlog := true;
				status := ReadVDigitizerFrameCount(nFrames, nTicks);
				if status = noErr then
					if (0 <= nFrames) and (nFrames <= 256) then
						FramesToAverage := nFrames;
			end
		else
			CustomALUDlog := false;
	end;


	procedure StopDigitizing;
		var
			frames, memsize: integer;
			status: OSErr;
			nFrames, nTicks: LongInt;
			oldPort: GrafPtr;
	begin
		if digitizing then
			with info^ do begin
					{  Save the current Grafport.		}
					GetPort(oldPort);
					SetPort(wptr);
					changes := true;
					frames := -1;
					status := CaptureVDigitizerFrames(frames, vdNone, vdSource, nil, nil, PicRect, nil, PicRect, wptr, PicRect);
					if status = noErr then begin
							status := ReadVDigitizerFrameCount(nFrames, nTicks);
							ShowVDFrameRate('', nTicks, nFrames);
							if not ScaleToFitWindow then
								magnification := 1.0;
							HideCursor;
{** X    if HighlightSaturatedPixels then }
{** X    UnHighlightPixels; }
							CaptureFrameOffscreen;
							InvalRect(CGrafPort(wptr^).PortRect);
							ShowCursor;
							Digitizing := false;
							ContinuousHistogram := false;
							BinaryPic := false;
							with info^ do begin
									title := 'Camera';
									UpdateTitleBar;
									if HighlightSaturatedPixels then
										UnHighlightPixels;
								end;
							if (BlankFieldInfo <> nil) and not OptionKeyDown then
								CorrectShading;
					{ If the window is scaled, turn off scaling for digitizer window. }
{if (ScaleToFitWindow = true) then begin}
{ScaleToFitWindow := false;}
{ScaleToFit;}
{end;}
							if VideoControl <> nil then
								RefreshVideoControl;
						end
					else begin
							digitizing := false;
{ PutMessage('Had a problem capturing frame for movie'); }
						end;
					SetPort(oldPort);
				end;
	end;


	procedure AdjustDigitizeRect;  { (grabRect: Rect); }
		var
			status: OSErr;
	begin
		status := AdjustVDigitizerGrabRect(grabRect);
	end;


	procedure MaintainDigitizing;
		var
			status: OSErr;
	begin
		status := TaskVDigitizers;
	end;


	function GetVDPixel (lh, lv: integer): integer;
		var
			p: ptr;
			gloc: Point;
			llh, llv: LongInt;
			tPort: GrafPtr;
	begin
		HideCursor;
		with Info^ do begin
				if (lh < 0) or (lv < 0) or (lh >= PixelsPerLine) or (lv >= nlines) then begin
						GetVDPixel := WhiteIndex;
						exit(GetVDPixel);
					end;
				gloc.h := lh;
				gloc.v := lv;
				GetPort(tPort);
				SetPort(wptr);
				OffscreenToScreen(gloc);
				LocalToGlobal(gloc);
				llh := LongInt(gloc.h);
				llv := LongInt(gloc.v);
				p := ptr(LongInt(ScreenBase) + llh + ScreenRowBytes * llv);
				GetVDPixel := BAND(p^, 255);
				SetPort(tPort);
			end;
		ShowCursor;
	end;


	function GrabClipBufRect: OSErr;
		var
			buffer, top, left: integer;
			grabRect: Rect;
	begin
		with ClipBufInfo^ do begin
				HideCursor;
				buffer := 1;
				HLock(handle(osPort^.portPixMap));
				grabRect := VDigitizerInfo^.RoiRect;
				top := grabRect.top;
				left := grabRect.left;
				GrabClipBufRect := ReadVDigitizerFrmeBuf(buffer, top, left, osPort^.portPixMap, nil);
				HUnlock(handle(osPort^.portPixMap));
				ShowCursor;
			end;
	end;


	function GrabRectToClipBuf;
		var
			frames, buffers: integer;
			grabRect: Rect;
			status: OSErr;
	begin
		grabRect := VDigitizerInfo^.RoiRect;
		frames := 1;
		status := AdjustVDigitizerGrabRect(grabRect);
		status := GetVDigitizerNumBuffers(nil, buffers);
		if buffers > 0 then begin
				status := CaptureVDigitizerFrames(frames, vdNone, vdSource, nil, nil, grabRect, nil, grabRect, nil, grabRect);
				if status = noErr then
					status := GrabClipBufRect;
				GrabRectToClipBuf := status;
			end
		else begin
				PutMessage('You must have a video digitizer card with a frame buffer to do Live Paste.');
				GrabRectToClipBuf := vdNotSupported;
			end;
	end;


	procedure CaptureAndDisplayFrame;
		var
			frames, buffers: integer;
			grabRect: Rect;
			status: OSErr;
	begin
		grabRect := VDigitizerInfo^.PicRect;
		frames := 1;
		status := AdjustVDigitizerGrabRect(grabRect);
		status := CaptureVDigitizerFrames(frames, vdNone, vdSource, nil, nil, grabRect, nil, grabRect, nil, grabRect);
		CaptureFrameOffscreen;
		UpdatePicWindow;
	end;


function StartContinuousHistogram; { :Boolean; }
	var
		status: OSErr;
		doesHist: Boolean;
begin
	if NotInBounds then begin
			StartContinuousHistogram := false;
			exit(StartContinuousHistogram);
		end;
	status := TestVDigitizerFeature(nil, vdFeBLiveHistogram, doesHist);
	if not doesHist then begin
			PutMessage('Sorry, the selected video digitizer does not support live histograms. ');
			StartContinuousHistogram := false;
			exit(StartContinuousHistogram);
		end;
	if ContinuousHistogram then
		ContinuousHistogram := false
	else begin
			ContinuousHistogram := true;
			if info <> NoInfo then
				with info^ do begin
						RoiType := NoRoi;
						RoiRect := SrcRect;
					end;
		end;
end;


		{  GetLiveHistogram is in Analysis.p. }


		{		This procedure takes the current image shown in the camera window and copies			}
		{		it to the Background Image pixMap.  If the Background Image pixMap is not							}
		{		open yet, it creates the pixMap.					}
		{		}
procedure GetNewBkgImage;
	var
		SaveInfo, SaveBFInfo: InfoPtr;
		src, dst: ptr;
		temp: integer;
		width, height, i: integer;
		offset: LongInt;
		didIt: boolean;
begin

			{		Make sure we have a window to copy from		}
	if info^.PictureType = VDigitizerType then begin

					{  If BkgImageInfo exists, check to see if the window is big enough}
			if BkgImageInfo <> nil then begin
					if not EqualRect(Info^.wptr^.portRect, BkgImageInfo^.wptr^.portRect) then begin
							SaveInfo := info;
							SaveBFInfo := BlankFieldInfo;
							temp := CloseAWindow(BkgImageInfo^.wptr);

									{  Restore all of the infoPtr information  }
							BlankFieldInfo := SaveBFInfo;
							info := SaveInfo;
						end {if not EqualRect  }
					else begin

									{  Rectangles are the same, so just copy the data  }
							with Info^ do begin
									width := RoiRect.right - RoiRect.left;
									height := RoiRect.bottom - RoiRect.top;
									offset := LongInt(RoiRect.top) * BytesPerRow + LongInt(RoiRect.left);

									src := ptr(ord4(PicBaseAddr) + offset);
									dst := BkgImageInfo^.PicBaseAddr;
									for i := 0 to height - 1 do begin
											BlockMove(src, dst, width);
											src := ptr(ord4(src) + BytesPerRow);
											dst := ptr(ord4(dst) + width);
										end;  {for i := 0 }
								end;  {with Info^}

									{  Update the on-screen window  }
							SaveInfo := info;
							info := BkgImageInfo;
							UpdatePicWindow;
							info := SaveInfo;
						end;  {  if not EqualRect  else begin}
				end;  {if BkgImageInfo <> nil}

					{		If the Background Image Window doesn't exist, create one.		}
			if BkgImageInfo = nil then begin

							{  Save the current state of the capture window  }
					SaveInfo := info;
					SaveBFInfo := BlankFieldInfo;

 							{		Prevent StopDigitizing from doing shading correction.}
					BlankFieldInfo := nil;
					StopDigitizing;

							{  Make a duplicate window of the captured image  }
					if Duplicate('Background Image', true) then begin
								{  Mark the window type  }
							BlankFieldInfo^.PIctureType := BkgImage;
						end;

					info^.changes := true;

							{  Restore all of the infoPtr information  }
					BkgImageInfo := BlankFieldInfo;
					BlankFieldInfo := SaveBFInfo;
					info := SaveInfo;

					SelectWindow(Info^.wptr);
				end;  {if BkgImageInfo = nil}
		end;  {if info^.PictureType}
end;  {procedure GetNewBkgImage}


		{  This procedure determines which video operations are supported by the		}
		{ currently selected digitizer, and enables / disables the menu selections			}
procedure CheckVdFuncs;
	var
		lclVDMInfoPtr: VDMInfoPtr;
		lclMode: integer;
		doesFunction: boolean;
		status: integer;
		CurrentVDigitizer: VDHandle;
begin

	CurrentVDigitizer := GetActiveVDigitizer;
	if CurrentVDigitizer <> nil then begin

			{  Get the mode information		}
			lclVDMInfoPtr := nil;
{lclVDMInfoPtr := VDMInfoPtr(NewPtr(SizeOf(VDModalInfo)));}
{if (lclVDMInfoPtr = nil) then begin}
{PutMessage('Out Of Memory');}
{Exit(CheckVdFuncs);}
{end;}

{status := GetVDigitizerMode(lclMode);}
{status := GetVDigitizerModeInfo(lclVDMInfoPtr, lclMode);}

			{  Test each of the digitizing functions  (make no assumptions)}
			{  Enable / disable each menu selection based on the test  }
			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBRawSample, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iRawSample)
			else
				DisableItem(gVideoProcMenuH, iRawSample);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBArithAvg, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iArithAve)
			else
				DisableItem(gVideoProcMenuH, iArithAve);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBGeomAvg, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iGeometAve)
			else
				DisableItem(gVideoProcMenuH, iGeometAve);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBIntegrate, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iIntegration)
			else
				DisableItem(gVideoProcMenuH, iIntegration);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBSubtract, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iSubtraction)
			else
				DisableItem(gVideoProcMenuH, iSubtraction);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBMultiply, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iMultiplication)
			else
				DisableItem(gVideoProcMenuH, iMultiplication);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBBgSubAvg, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iBkSubArAve)
			else
				DisableItem(gVideoProcMenuH, iBkSubArAve);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBBgSubGeomAvg, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iBkSubGeoAve)
			else
				DisableItem(gVideoProcMenuH, iBkSubGeoAve);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBBgSubIntegrate, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iBkSubIntegrate)
			else
				DisableItem(gVideoProcMenuH, iBkSubIntegrate);

			status := TestVDigitizerFunction(lclVDMInfoPtr, vdFuBCustoms, doesFunction);
			if doesFunction then
				EnableItem(gVideoProcMenuH, iCustomOp)
			else
				DisableItem(gVideoProcMenuH, iCustomOp);

			{  Release the allocated memory  }
{DisposPtr(ptr(lclVDMInfoPtr));}
		end
	else begin
			DisableItem(gVideoProcMenuH, iRawSample);
			DisableItem(gVideoProcMenuH, iArithAve);
			DisableItem(gVideoProcMenuH, iGeometAve);
			DisableItem(gVideoProcMenuH, iIntegration);
			DisableItem(gVideoProcMenuH, iSubtraction);
			DisableItem(gVideoProcMenuH, iMultiplication);
			DisableItem(gVideoProcMenuH, iBkSubArAve);
			DisableItem(gVideoProcMenuH, iBkSubGeoAve);
			DisableItem(gVideoProcMenuH, iBkSubIntegrate);
			DisableItem(gVideoProcMenuH, iCustomOp);
		end;
end;  { procedure CheckkVdFuncs}


end.