home *** CD-ROM | disk | FTP | other *** search
- unit Camera;
-
- {Routines used by the Image program for supporting the Data Translation}
- {QuickCapture card and the Scion Image Capture 2.}
-
- interface
-
-
- uses
- QuickDraw, Palettes, PrintTraps, globals, Utilities, Graphics, File1;
-
-
- procedure AverageFrames;
- procedure CaptureAndDisplayQCFrame;
- procedure HighlightPixels;
- procedure ShowTriggerMessage;
- procedure StartDigitizing;
- procedure StopDigitizing;
- procedure SetVideoChannel;
- function GetQCPixel (h, v: integer): integer;
- procedure CopyOffscreen (src, dst: PixMapHandle; sRect, dRect: rect);
- procedure GetQuickCaptureFrame;
- procedure GetScionFrame (DisplayPoint: point);
- procedure WaitForTrigger;
- procedure DoVideoOptions;
-
-
-
- implementation
-
- type
- IntPtr = ^integer;
-
- var
- SavePicBaseAddr: ptr;
- StopFlagLoc: IntPtr;
-
-
- procedure CorrectShadingOfLine (PicPtr, BFPtr: ptr; width, BFMean: integer);
- {}
- {VAR}
- { PicLine,BFLine:LinePtr;}
- { i,value:integer;}
- {BEGIN}
- { PicLine:=LinePtr(PicPtr);}
- { BFLine:=LinePtr(BFPtr);}
- { FOR i:=0 TO width-1 DO BEGIN}
- { value:=PicLine^[i];}
- { value:=255-value;}
- { value:=(LongInt(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;}
- { }
- {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}
- $82C2, { 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, $FFDE, { dbra d0,L1}
- $4CDF, $037F, { movem.l (sp)+,a0-a1/d0-d6}
- $4E5E, { unlk a6}
- $DEFC, $000C; { add.w #12,sp}
- {END;}
-
-
- procedure CorrectShading;
- var
- i: integer;
- offset: LongInt;
- p1, p2: ptr;
- str: str255;
- begin
- with info^ do begin
- if ImageSize <> BlankFieldInfo^.ImageSize then begin
- beep;
- exit(CorrectShading);
- end;
- ShowWatch;
- 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 i mod 96 = 0 then
- UpdatePicWindow;
- end;
- UpdatePicWindow;
- str := title;
- if SpatiallyCalibrated then
- str := concat(str, chr($13)); {Black Diamond}
- if DensityCalibrated then
- str := concat(str, '');
- if wptr <> nil then
- SetWTitle(wptr, concat(str, '(Corrected)'));
- end;
- end;
-
-
- procedure CopyOffscreen (src, dst: PixMapHandle; sRect, dRect: rect);
- begin
- hlock(handle(src));
- hlock(handle(dst));
- CopyBits(BitMapHandle(src)^^, BitMapHandle(dst)^^, sRect, dRect, SrcCopy, nil);
- hunlock(handle(src));
- hunlock(handle(dst));
- end;
-
-
- procedure StopDigitizing;
- begin
- if digitizing then
- with info^ do begin
- ShowFrameRate('', DTStartTicks, DTFrameCount);
- CopyOffscreen(qcPort^.portPixMap, osPort^.portPixMap, PicRect, PicRect);
- SetItem(SpecialMenuH, StartItem, 'Start Capturing');
- Digitizing := false;
- ContinuousHistogram := false;
- with info^ do
- if PictureType = QuickCaptureType then begin
- title := 'Camera';
- UpdateTitleBar;
- if HighlightSaturatedPixels then
- LoadLUT(ctable);
- end;
- if (BlankFieldInfo <> nil) and not OptionKeyDown then
- CorrectShading;
- end;
- end;
-
-
- procedure GetQuickCaptureFrame;
- var
- ticks, timeout: LongInt;
- begin
- if ExternalTrigger then begin {Wait for external trigger}
- ControlReg^ := BitAnd($82, 255);
- repeat
- if button then
- ExternalTrigger := false;
- until (ControlReg^ >= 0) or not ExternalTrigger;
- if Digitizing then
- StopDigitizing;
- end
- else begin
- TimeOut := TickCount + 30; {1/2sec. timeout}
- ControlReg^ := BitAnd($80, 255); {Start frame capture}
- while ControlReg^ < 0 do begin {Wait for it to complete}
- if TickCount > TimeOut then
- leave
- end;
- DTFrameCount := DTFrameCount + 1;
- end;
- end;
-
-
- procedure CaptureAndDisplayQCFrame;
- var
- tPort: GrafPtr;
- begin
- with info^ do begin
- if (PictureType <> QuickCaptureType) or (PixelsPerLine <> qcWidth) or (nlines <> qcHeight) then begin
- Digitizing := false;
- exit(CaptureAndDisplayQCFrame);
- end;
- GetQuickCaptureFrame;
- getPort(tPort);
- SetPort(wptr);
- hlock(handle(qcPort^.portPixMap));
- hlock(handle(CGrafPort(wptr^).PortPixMap));
- CopyBits(BitMapHandle(qcPort^.portPixMap)^^, BitMapHandle(CGrafPort(wptr^).PortPixMap)^^, SrcRect, wrect, SrcCopy, nil);
- hunlock(handle(qcPort^.portPixMap));
- hunlock(handle(CGrafPort(wptr^).PortPixMap));
- SetPort(tPort);
- end;
- end;
-
-
- procedure SetReg (index, value: integer);
- const
- RegOffset = $f5fe0;
- var
- reg: ptr;
- begin
- reg := ptr(ScionSlotBase + RegOffset + index * 4);
- reg^ := value;
- end;
-
-
- procedure ResetScion (GrabRect: rect; DisplayPoint: point);
- const
- ilutOffset = $f0000;
- LineStartsRamOffset = $f4000;
- type
- LineStartsArray = packed array[0..8191] of UnsignedByte;
- LineStartsType = ^LineStartsArray;
- var
- ScreenRowBytesx2: LongInt;
- LutPtr: ptr;
- LineStarts: LineStartsType;
- EvenStart, OddStart: LongInt;
- width, height, IndexOdd, IndexEven, index, i: integer;
- hstart, vstart: integer;
- begin
- ScreenRowBytesx2 := ScreenRowBytes * 2;
- LoadInputLookupTable(Ptr(ScionSlotBase + ilutOffset));
- with GrabRect, DisplayPoint do begin
- hstart := BitAnd(left, $fffc);
- vstart := BitAnd(top, $fffe);
- width := right - left;
- height := bottom - top;
- StopFlagLoc := IntPtr(LongInt(ScreenBase) + h + ScreenRowBytes * (v + height - 2) + 4);
- EvenStart := LongInt(ScreenBase) + h + ScreenRowBytes * v;
- OddStart := EvenStart + ScreenRowBytes;
- IndexOdd := 0;
- IndexEven := (height div 2) * 16;
- end;
- LineStarts := LineStartsType(ScionSlotBase + LineStartsRamOffset);
- for i := 1 to height div 2 do begin
- LineStarts^[IndexOdd] := BSR(BitAnd(OddStart, $ff000000), 24);
- LineStarts^[IndexOdd + 4] := BSR(BitAnd(OddStart, $ff0000), 16);
- LineStarts^[IndexOdd + 8] := BSR(BitAnd(OddStart, $ff00), 8);
- LineStarts^[IndexOdd + 12] := BitAnd(OddStart, $fc);
- LineStarts^[IndexEven] := BSR(BitAnd(EvenStart, $ff000000), 24);
- LineStarts^[IndexEven + 4] := BSR(BitAnd(EvenStart, $ff0000), 16);
- LineStarts^[IndexEven + 8] := BSR(BitAnd(EvenStart, $ff00), 8);
- LineStarts^[IndexEven + 12] := BitAnd(EvenStart, $fc);
- IndexOdd := IndexOdd + 16;
- IndexEven := IndexEven + 16;
- OddStart := OddStart + ScreenRowBytesx2;
- EvenStart := EvenStart + ScreenRowBytesx2;
- end;
- Index := height * 16;
- LineStarts^[Index] := 0;
- LineStarts^[Index + 4] := 0;
- LineStarts^[Index + 8] := 0;
- LineStarts^[Index + 12] := 1;
- SetReg(1, 0);
- SetReg(2, 162 - (width div 4));
- SetReg(3, 0);
- SetReg(4, 225 - (hstart div 4));
- SetReg(5, 255 - (width div 4));
- SetReg(6, 241 - (vstart div 2));
- SetReg(7, 255 - (height div 2));
- end;
-
-
- procedure GetScionFrame (DisplayPoint: point);
- {Captures a single Scion frame to screen memory.}
- type
- IntPtr = ^integer;
- var
- FlagLoc: IntPtr;
- StartTime: LongInt;
- myMMUMode: signedbyte;
- begin
- with DisplayPoint do
- FlagLoc := IntPtr(LongInt(ScreenBase) + h + ScreenRowBytes * v + 4);
- StartTime := TickCount;
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- FlagLoc^ := $00ff;
- SetReg(1, BitOr(128, VideoChannel * 4)); {Grab Enable}
- while FlagLoc^ = $00ff do
- if TickCount > (StartTime + 5) then begin
- SetReg(1, 0); {Stop Grabbing}
- SwapMMUMode(myMMUMode);
- exit(GetScionFrame)
- end;
- StopFlagLoc^ := $00ff;
- while StopFlagLoc^ = $00ff do begin
- end;
- SetReg(1, 0); {Stop Grabbing}
- SwapMMUMode(myMMUMode);
- end;
-
-
- function GetScreenPixel (h, v: integer): integer;
- var
- offset: LongInt;
- p: ptr;
- begin
- offset := LongInt(v) * ScreenRowBytes + h;
- p := ptr(ord4(ScreenBase) + offset);
- GetScreenPixel := BAND(p^, 255);
- end;
-
-
- procedure CopyScionFrameOffscreen (DisplayPoint: point; wwidth, wheight: integer);
- var
- src, dst: ptr;
- line: integer;
- begin
- with Info^ do begin
- with DisplayPoint do
- src := ptr(LongInt(ScreenBase) + h + ScreenRowBytes * v);
- dst := ptr(LongInt(PicBaseAddr));
- for line := 1 to wheight do begin
- BlockMove(src, dst, wwidth);
- src := ptr(ord4(src) + ScreenRowBytes);
- dst := ptr(ord4(dst) + BytesPerRow);
- end;
- end;
- end;
-
-
- procedure DoMiniEventLoop (FullScreenMode: boolean);
- var
- loc: point;
- event: EventRecord;
- begin
- FlushEvents(EveryEvent, 0);
- if not FullScreenMode then
- DrawLabels('X:', 'Y:', 'Value:');
- repeat
- GetMouse(loc);
- LocalToGlobal(loc);
- if not FullScreenMode then
- with loc do
- Show3Values(h, v, GetScreenPixel(h, v));
- until WaitNextEvent(mDownMask + KeyDownMask, Event, 0, nil);
- end;
-
-
- procedure CaptureUsingScion;
- var
- GrabRect, ScreenSrcRect: rect;
- DisplayPoint: point;
- FullScreenMode: boolean;
- wwidth, wheight: integer;
- tPort: GrafPtr;
- SaveBackgroundColor, hstart, vstart: integer;
- ignore: integer;
- mloc: point;
- MainDevice: GDHandle;
- SrcPixMap: PixMapHandle;
- myMMUMode: signedbyte;
- FlagLoc: IntPtr;
- StartTime: LongInt;
- grabbing: boolean;
- begin
- FullScreenMode := OptionKeyDown and (ScreenWidth = 640);
- if FullScreenMode or (ScreenWidth > 640) then begin
- wwidth := MaxScionWidth;
- wheight := 480
- end
- else begin
- wwidth := 552;
- if wwidth > MaxScionWidth then
- wwidth := MaxScionWidth;
- wheight := 436;
- end;
- if ScionInfo <> nil then
- with ScionInfo^.wrect, ScionInfo^ do
- if (wwidth <> right) or (wheight <> bottom) then begin
- changes := false;
- ignore := CloseAWindow(wptr);
- end;
- if (ScionInfo <> nil) and (info^.PictureType <> ScionType) then begin
- SelectWindow(ScionInfo^.wptr);
- info := ScionInfo;
- end;
- if ScionInfo <> nil then
- BringToFront(ScionInfo^.wptr);
- with info^ do
- if PictureType <> ScionType then begin
- if not NewPicWindow('Camera(Scion)', wwidth, wheight) then begin
- beep;
- exit(CaptureUsingScion)
- end;
- ScionInfo := info;
- end;
- KillRoi;
- with info^ do begin
- PictureType := ScionType;
- changes := true;
- UpdateTitleBar;
- end;
- hstart := (640 - wwidth) div 2;
- vstart := (480 - wheight) div 2;
- SetRect(GrabRect, hstart, vstart, hstart + wwidth, vstart + wheight);
- if FullScreenMode then
- with DisplayPoint do begin
- h := BitAnd((640 - wwidth) div 2, $fffc);
- v := 0;
- end
- else
- with DisplayPoint do begin
- h := PicLeftBase;
- v := PicTopBase;
- end;
- ResetScion(GrabRect, DisplayPoint);
- if FullScreenMode then begin
- GetPort(tPort);
- SaveBackgroundColor := BackgroundIndex;
- SetBackgroundColor(BlackIndex);
- EraseScreen;
- end;
- if info^.magnification <> 1.0 then
- Unzoom;
- with DisplayPoint do
- FlagLoc := IntPtr(LongInt(ScreenBase) + h + ScreenRowBytes * v + 4);
- StartTime := TickCount;
- grabbing := true;
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- FlagLoc^ := $00ff;
- SetReg(1, BitOr(128, VideoChannel * 4)); {Grab Enable}
- while FlagLoc^ = $00ff do
- if TickCount > (StartTime + 5) then begin
- SetReg(1, 0); {Stop Grabbing}
- FlagLoc^ := $0000;
- SwapMMUMode(myMMUMode);
- grabbing := false;
- end;
- if grabbing then begin
- SwapMMUMode(myMMUMode);
- DoMiniEventLoop(FullScreenMode);
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- StopFlagLoc^ := $00ff;
- while StopFlagLoc^ = $00ff do begin
- end;
- SetReg(1, 0); {Stop Grabbing}
- SwapMMUMode(myMMUMode);
- HideCursor;
- GetScionFrame(DisplayPoint);
- end;
- MainDevice := GetMainDevice;
- SrcPixMap := MainDevice^^.gdPMap;
- with DisplayPoint, ScreenSrcRect do begin
- left := h;
- top := v;
- right := left + wwidth;
- bottom := top + wheight;
- end;
- with info^ do begin
- CopyOffscreen(SrcPixMap, osPort^.portPixMap, ScreenSrcRect, PicRect);
- ShowCursor;
- if FullScreenMode then begin
- RestoreScreen;
- SetBackgroundColor(SaveBackgroundColor);
- SetPort(tPort);
- end;
- title := 'Camera';
- UpdateTitleBar;
- end; {with}
- if (BlankFieldInfo <> nil) and not OptionKeyDown then
- CorrectShading;
- FlushEvents(EveryEvent, 0);
- end;
-
-
- procedure HighlightPixels;
- var
- lut: MyCSpecArray;
- begin
- with info^ do begin
- lut := ctable;
- with lut[1].rgb do begin
- red := 0;
- green := -1;
- blue := 0;
- end;
- with lut[254].rgb do begin
- red := -1;
- green := 0;
- blue := 0;
- end;
- LoadLUT(lut);
- end;
- end;
-
-
- procedure ShowTriggerMessage;
- begin
- if ExternalTrigger and (FrameGrabber = QuickCapture) then
- ShowMessage(concat('EXTERNAL TRIGGER MODE', cr, '(Press mouse button to exit)'));
- end;
-
-
- procedure StartDigitizing;
- var
- i, width, height: integer;
- trect: rect;
- NewWindow: boolean;
- begin
- if FrameGrabber = Scion then begin
- if HighlightSaturatedPixels then
- HighlightPixels;
- CaptureUsingScion;
- if HighlightSaturatedPixels then
- LoadLUT(info^.ctable);
- exit(StartDigitizing)
- end;
- if Digitizing then begin
- StopDigitizing;
- if BlankFieldInfo <> nil then
- wait(15);
- FlushEvents(EveryEvent, 0); {In case user holds key down too long}
- exit(StartDigitizing)
- end;
- if FrameGrabber = NoFrameGrabber then begin
- PutMessage('Capturing requires a Data Translation or SCION frame grabber card.');
- exit(StartDigitizing)
- end;
- if (QuickCaptureInfo <> nil) and (info^.PictureType <> QuickCaptureType) then begin
- SelectWindow(QuickCaptureInfo^.wptr);
- info := QuickCaptureInfo;
- end;
- NewWindow := false;
- with info^ do
- if (PictureType <> QuickCaptureType) or (PixelsPerLine <> qcWidth) or (nlines <> qcHeight) then begin
- if not NewPicWindow('Camera', qcWidth, qcHeight) then
- exit(StartDigitizing);
- NewWindow := true;
- end;
- with info^ do begin
- PictureType := QuickCaptureType;
- QuickCaptureInfo := info;
- if NewWindow and (not EqualRect(SrcRect, PicRect)) then {Center Frame}
- with SrcRect do begin
- width := right - left;
- height := bottom - top;
- left := (PicRect.right - width) div 2;
- right := left + width;
- top := (PicRect.bottom - height) div 2;
- bottom := top + height;
- end;
- KillRoi;
- if ScaleToFitWindow then
- ScaleToFit;
- with SrcRect do begin
- width := right - left;
- left := band(left, $fffc);
- right := left + width;
- end;
- GetWindowRect(wptr, trect);
- with trect do
- if band(left, 3) <> 0 then
- MoveWindow(wptr, band(left, $fffc), top, true); {Forces window to be word aligned}
- with SrcRect do {Prevents bus errors when Camera window moved.}
- if (top = 0) and (bottom < PicRect.bottom) then begin
- top := top + 1;
- bottom := bottom + 1;
- end;
- ResetQuickCapture;
- Digitizing := true;
- SetItem(SpecialMenuH, StartItem, 'Stop Capturing');
- changes := true;
- BinaryPic := false;
- UpdateTitleBar;
- if HighlightSaturatedPixels then
- HighlightPixels;
- end; {with info}
- DTFrameCount := 0;
- DTStartTicks := TickCount;
- ContinuousHistogram := false;
- ShowTriggerMessage;
- end;
-
-
- procedure AddLineToSum (src, dst: ptr; width: LongInt);
- {$IFC false}
- type
- SumLineType = array[0..2047] of integer;
- fptr = ^SumLineType;
- var
- FrameLine: LinePtr;
- SumLine: fptr;
- i: integer;
- begin
- FrameLine := LinePtr(src);
- SumLine := fptr(dst);
- for i := 0 to width - 1 do
- SumLine^[i] := SumLine^[i] + FrameLine^[i];
- end;
- {$ENDC}
- inline
- {a0=data pointer}
- {a1=sum buffer pointer}
- {d0=count}
- {d1=pixel value}
- {d2=temp}
- $4E56, $0000, {link a6,#0}
- $48E7, $E0C0, {movem.l a0-a1/d0-d2,-(sp)}
- $206E, $000C, {move.l 12(a6),a0}
- $226E, $0008, {move.l 8(a6),a1}
- $202E, $0004, {move.l 4(a6),d0}
- $5380, {subq.l #1,d0}
- $4281, {clr.l d1}
- $4282, {clr.l d2}
- $1218, {L1 move.b (a0)+,d1}
- $3411, {move.w (a1),d2}
- $D441, {add.w d1,d2}
- $32C2, {move.w d2,(a1)+}
- $51C8, $FFF6, {dbra d0,L1}
- $4CDF, $0307, {movem.l (sp)+,a0-a1/d0-d2}
- $4E5E, {unlk a6}
- $DEFC, $000C; {add.w #12,sp}
-
-
-
- function DoAveragingOptions: boolean;
- const
- FramesID = 4;
- SumID = 5;
- var
- mylog: DialogPtr;
- item, i: integer;
- begin
- InitCursor;
- mylog := GetNewDialog(140, nil, pointer(-1));
- SetDNum(MyLog, FramesID, FramesToAverage);
- SetDialogItem(mylog, SumID, ord(SumFrames));
- SelIText(MyLog, FramesID, 0, 32767);
- OutlineButton(MyLog, ok, 16);
- repeat
- ModalDialog(nil, item);
- if item = FramesID then
- FramesToAverage := GetDNum(MyLog, FramesID);
- if item = SumID then begin
- SumFrames := not SumFrames;
- SetDialogItem(mylog, SumID, ord(SumFrames));
- end;
- until (item = ok) or (item = cancel);
- DisposDialog(mylog);
- if FramesToAverage < 2 then
- FramesToAverage := 2;
- DoAveragingOptions := item <> cancel;
- end;
-
-
- procedure AverageFrames;
- type
- IntPtr = ^integer;
- SumLineType = array[0..2047] of integer;
- sptr = ^SumLineType;
- var
- AutoSelectAll: boolean;
- SelectionSize, FrameBufferSize, offset, StartTicks: LongInt;
- SumBase, src, srcbase, dst, OffscreenBase: ptr;
- str1, str2: str255;
- xLines, xPixelsPerLine, xPixelsPerLine2, frame, line, pixel: integer;
- aline: LineType;
- GrabRect: rect;
- DisplayPoint: point;
- hstart, vstart, wwidth, wheight, MinV, MaxV, value: integer;
- j, range, FramesAveraged: integer;
- SrcRowBytes, DstRowBytes, i: LongInt;
- iptr: IntPtr;
- FrameLine: LinePtr;
- SumLine: sptr;
- SaveBlankFieldInfo: InfoPtr;
- myMMUMode: signedbyte;
- begin
- if (info <> QuickCaptureInfo) and (info <> ScionInfo) then begin
- PutMessage('You must have an active Camera window(created using Start Capturing) in order to average frames.');
- exit(AverageFrames)
- end;
- if NotRectangular or NotinBounds then
- exit(AverageFrames);
- if not OptionKeyWasDown then begin
- if not DoAveragingOptions then
- exit(AverageFrames);
- end;
- SaveBlankFieldInfo := BlankFieldInfo;
- BlankFieldInfo := nil; {We don't want to do shading correction now}
- StopDigitizing;
- BlankFieldInfo := SaveBlankFieldInfo;
- OptionKeyWasDown := false;
- DrawLabels('Frame:', 'Total:', '');
- ShowTriggerMessage;
- ShowWatch;
- AutoSelectAll := not Info^.RoiShowing;
- if AutoSelectAll then
- SelectAll(false);
- with info^.RoiRect do
- SelectionSize := (LongInt(right) - left) * (bottom - top);
- FrameBufferSize := SelectionSize * 2;
- if FrameBufferSize > BigBufSize then begin
- NumToString(FrameBufferSize div 1024, str1);
- NumToString(BigBufSize div 1024, str2);
- str2 := concat(str1, 'K bytes are required, but only ', str2, 'K bytes are available.');
- PutMessage(concat('There is not enough memory to do the requested frame averaging. ', str2));
- if AutoSelectAll or (BlankFieldInfo <> nil) then
- KillRoi
- else
- ShowRoi;
- exit(AverageFrames)
- end;
- WhatToUndo := NothingToUndo;
- WhatsOnClip := Nothing;
- SumBase := BigBuf;
- if FrameGrabber = QuickCapture then begin
- ContinuousHistogram := false;
- ResetQuickCapture
- end
- else begin
- with info^.wrect do begin
- wwidth := right;
- wheight := bottom;
- end;
- hstart := (640 - wwidth) div 2;
- vstart := (480 - wheight) div 2;
- SetRect(GrabRect, hstart, vstart, hstart + wwidth, vstart + wheight);
- with DisplayPoint do begin
- h := PicLeftBase;
- v := PicTopBase;
- end;
- ResetScion(GrabRect, DisplayPoint);
- HideCursor;
- end;
- with info^, info^.RoiRect do begin
- offset := left + LongInt(top) * BytesPerRow;
- OffscreenBase := ptr(ord4(PicBaseAddr) + offset);
- if FrameGrabber = QuickCapture then begin
- offset := left + LongInt(top) * qcRowBytes;
- srcbase := ptr(ord4(ptr(DTSlotBase)) + offset);
- SrcRowBytes := qcRowBytes;
- end
- else
- with DisplayPoint do begin
- BringToFront(wptr);
- offset := left + h + (v + top) * ScreenRowBytes;
- srcbase := ptr(ord4(ScreenBase) + offset);
- SrcRowBytes := ScreenRowBytes;
- end;
- xLines := bottom - top;
- xPixelsPerLine := right - left;
- xPixelsPerLine2 := xPixelsPerLine * 2;
- end;
- dst := SumBase;
- for line := 1 to xLines do begin {zero buffer}
- BlockMove(ptr(BlankLine), dst, xPixelsPerLine2);
- dst := ptr(ord4(dst) + xPixelsPerLine2);
- end;
- info^.title := 'Camera';
- UpdateTitleBar;
- StartTicks := TickCount;
- for frame := 0 to FramesToAverage - 1 do begin
- Show2Values(frame + 1, FramesToAverage);
- if FrameGrabber = QuickCapture then
- GetQuickCaptureFrame
- else
- GetScionFrame(DisplayPoint);
- src := srcbase;
- dst := SumBase;
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- for line := 1 to xLines do begin
- AddLineToSum(src, dst, xPixelsPerLine);
- src := ptr(ord4(src) + SrcRowBytes);
- dst := ptr(ord4(dst) + xPixelsPerLine2);
- end;
- SwapMMUMode(myMMUMode);
- if FrameGrabber = QuickCapture then
- UpdateScreen(info^.RoiRect);
- if CommandPeriod then begin
- beep;
- if AutoSelectAll then
- KillRoi
- else
- ShowRoi;
- exit(AverageFrames);
- end;
- end; {for}
- src := SumBase;
- dst := OffscreenBase;
- DstRowBytes := info^.BytesPerRow;
- if SumFrames then begin
- MinV := 32767;
- MaxV := 0;
- iptr := IntPtr(src);
- for i := 1 to SelectionSize do begin
- value := iptr^;
- if value > MaxV then
- MaxV := value;
- if value < MinV then
- MinV := value;
- iptr := IntPtr(ord4(iptr) + 2);
- end;
- range := MaxV - MinV;
- if range <> 0 then
- for line := 1 to xLines do begin
- SumLine := sptr(src);
- FrameLine := LinePtr(dst);
- for j := 0 to xPixelsPerLine - 1 do begin
- value := SumLine^[j] - MinV + 1;
- value := LongInt(value) * 254 div range;
- FrameLine^[j] := value;
- end;
- src := ptr(ord4(src) + xPixelsPerLine2);
- dst := ptr(ord4(dst) + DstRowBytes);
- end
- else
- beep;
- end
- else
- for line := 1 to xLines do begin
- SumLine := sptr(src);
- FrameLine := LinePtr(dst);
- for j := 0 to xPixelsPerLine - 1 do
- FrameLine^[j] := SumLine^[j] div FramesToAverage;
- src := ptr(ord4(src) + xPixelsPerLine2);
- dst := ptr(ord4(dst) + DstRowBytes);
- end;
- RealToString((TickCount - StartTicks) / 60.0, 1, 2, str1);
- ShowFrameRate(concat(Long2str(FramesToAverage), ' frames', cr, str1, ' seconds', cr), StartTicks, FramesToAverage);
- UpdatePicWindow;
- if AutoSelectAll then
- KillRoi
- else
- ShowRoi;
- if BlankFieldInfo <> nil then
- CorrectShading;
- end;
-
-
-
- function GetQCPixel (h, v: integer): integer;
- var
- offset: LongInt;
- p: ptr;
- begin
- with Info^ do begin
- if (h < 0) or (v < 0) or (h >= qcWidth) or (v >= qcHeight) then begin
- GetQCPixel := WhiteIndex;
- exit(GetQCPixel);
- end;
- offset := LongInt(v) * qcRowBytes + h;
- if offset >= LongInt(qcHeight) * qcRowBytes then begin
- GetQCPixel := WhiteIndex;
- exit(GetQCPixel);
- end;
- p := ptr(ord4(ptr(DTSlotBase)) + offset);
- GetQCPixel := BAND(p^, 255);
- end;
- end;
-
-
- procedure WaitForTrigger;
- begin
- StopDigitizing;
- ShowWatch;
- if FrameGrabber = QuickCapture then begin
- ControlReg^ := BitAnd($82, 255); {Wait for external trigger and capture one frame}
- repeat
- until (ControlReg^ >= 0) or Button; {Wait for it to complete}
- end
- else
- repeat
- until Button;
- end;
-
-
- procedure DoVideoOptions;
- const
- InvertID = 3;
- HighLightID = 4;
- OscillatingID = 5;
- TriggerID = 6;
- ChannelID = 7;
- MaxScionWidthID = 8;
- BlindID = 11;
- var
- mylog: DialogPtr;
- item, i: integer;
- SaveInvert, SaveOscillating, SaveHighLight, WasDigitizing: boolean;
- SaveMaxWidth, SaveChannel: integer;
- begin
- InitCursor;
- SaveInvert := InvertVideo;
- SaveMaxWidth := MaxScionWidth;
- SaveOscillating := OscillatingMovies;
- SaveChannel := VideoChannel;
- SaveHighlight := HighlightSaturatedPixels;
- mylog := GetNewDialog(130, nil, pointer(-1));
- SetDNum(MyLog, MaxScionWidthID, MaxScionWidth);
- SetDNum(MyLog, ChannelID, VideoChannel);
- SetDialogItem(mylog, InvertID, ord(InvertVideo));
- SetDialogItem(mylog, HighlightID, ord(HighlightSaturatedPixels));
- SetDialogItem(mylog, OscillatingID, ord(OscillatingMovies));
- SetDialogItem(mylog, TriggerID, ord(ExternalTrigger));
- SetDialogItem(mylog, BlindID, ord(BlindMovieCapture));
- OutlineButton(MyLog, ok, 16);
- WasDigitizing := Digitizing;
- StopDigitizing;
- repeat
- ModalDialog(nil, item);
- if item = ChannelID then begin
- VideoChannel := GetDNum(MyLog, ChannelID);
- if (VideoChannel < 0) or (VideoChannel > 3) then begin
- VideoChannel := SaveChannel;
- SetDNum(MyLog, ChannelID, VideoChannel);
- end;
- end;
- if item = MaxScionWidthID then begin
- MaxScionWidth := BitAnd(GetDNum(MyLog, MaxScionWidthID), $fffc);
- if (MaxScionWidth < 0) or (MaxScionWidth > 640) then begin
- beep;
- MaxScionWidth := SaveMaxWidth;
- SetDNum(MyLog, MaxScionWidthID, MaxScionWidth);
- end;
- end;
- if item = InvertID then begin
- InvertVideo := not InvertVideo;
- SetDialogItem(mylog, InvertID, ord(InvertVideo));
- end;
- if item = HighlightID then begin
- HighlightSaturatedPixels := not HighlightSaturatedPixels;
- SetDialogItem(mylog, HighlightID, ord(HighlightSaturatedPixels));
- end;
- if item = OscillatingID then begin
- OscillatingMovies := not OscillatingMovies;
- SetDialogItem(mylog, OscillatingID, ord(OscillatingMovies));
- end;
- if item = TriggerID then begin
- ExternalTrigger := not ExternalTrigger;
- SetDialogItem(mylog, TriggerID, ord(ExternalTrigger));
- end;
- if item = BlindID then begin
- BlindMovieCapture := not BlindMovieCapture;
- SetDialogItem(mylog, BlindID, ord(BlindMovieCapture));
- end;
- until (item = ok) or (item = cancel);
- DisposDialog(mylog);
- if FramesToAverage < 2 then
- FramesToAverage := 2;
- if item = cancel then begin
- MaxScionWidth := SaveMaxWidth;
- OscillatingMovies := SaveOscillating;
- InvertVideo := SaveInvert;
- VideoChannel := SaveChannel;
- HighlightSaturatedPixels := SaveHighlight;
- end;
- if (FrameGrabber = Scion) and (ExternalTrigger or BlindMovieCapture) then begin
- PutMessage('External triggering and blind movie capture are not supported with the SCION frame grabber card.');
- ExternalTrigger := false;
- BlindMovieCapture := false;
- end;
- if WasDigitizing and (not ExternalTrigger) then
- StartDigitizing;
- end;
-
- end.