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 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 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.