📄 cdib.pas
字号:
begin
Result := GSinTable2[Trunc(Angle * CSinCosTablePrecision)];
end;
function LastError: string;
var
OutputMessage: PChar;
begin
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER,
nil,
GetLastError,
0, @OutputMessage,
0,
nil);
Result := string(OutputMessage);
end;
function ColorToPixel32(const AColor: TColor): TPixel32; register;
asm
Call ColorToRGB
bswap EAX
SHR EAX, 8
end;
function Pixel32ToColor(const APixel32: TPixel32): TColor; register;
asm
shl EAX, 8
bswap EAX
end;
function GetRotatedPoint(X, Y, Radius, Angle: Extended): TPoint;
var
Radians: Extended;
begin
Assert((Angle >= 0) and (Angle < 360));
Radians := DegToRad(Angle - 90);
Result.X := Ceil(Cos(Radians) * Radius + X);
Result.Y := Ceil(Sin(Radians) * Radius + Y);
end;
function GetRotatedSize(Width, Height: Word; Angle: Extended;
ScaleX, ScaleY: Extended): TPoint;
var
Radians: Extended;
ScaledWidth, ScaledHeight: Extended;
begin
Assert((Angle >= 0) and (Angle < 360));
Radians := DegToRad(-Angle);
ScaledWidth := Width * ScaleX / 100;
ScaledHeight := Height * ScaleY / 100;
Result := Point(Ceil(Abs(ScaledWidth * Cos(Radians)) + Abs(ScaledHeight * Sin(Radians))),
Ceil(Abs(ScaledWidth * Sin(Radians)) + Abs(ScaledHeight * Cos(Radians))));
Result.X := Result.X - (Result.X mod 2);
Result.Y := Result.Y - (Result.Y mod 2);
end;
function Largest(A, B: Integer): Integer;
begin
if A > B then
Result := A
else
Result := B;
end;
function RelativeAngle(X1, Y1, X2, Y2: Integer): Extended;
var
Theta: Extended;
XDist, YDist: Integer;
begin
Result := 0;
//arctan((y2-y1)/(x2-x1))
XDist := X2 - X1;
YDist := Y1 - Y2;
if (XDist = 0) and (YDist = 0) then exit;
if YDist = 0 then
Theta := arctan((X2 - X1))
else
Theta := arctan((X2 - X1) / (Y1 - Y2));
Result := RadToDeg(Theta);
if (X2 >= X1) and (Y2 >= Y1) then //Quadrant = 2
Result := 90 + (90 - Abs(Result))
else if (X2 <= X1) and (Y2 >= Y1) then //Quadrant = 3
Result := 180 + Abs(Result)
else if (X2 <= X1) and (Y2 <= Y1) then //Quadrant = 4
Result := 270 + (90 - Abs(Result));
end;
function SafeAngle(Angle: Extended): Extended;
begin
while Angle < 0 do
Angle := Angle + 360;
while Angle >= 360 do
Angle := Angle - 360;
Result := Angle;
end;
function Smallest(A, B: Integer): Integer;
begin
if A < B then
Result := A
else
Result := B;
end;
{ TDIBFilter }
constructor TDIBFilter.Create;
begin
inherited;
Opacity := 255;
RedBias := 0;
GreenBias := 0;
BlueBias := 0;
Factor := 0;
end;
class function TDIBFilter.GetDisplayName: string;
begin
Result := '(Unknown)';
end;
{ TAbstractSuperDIB }
procedure TAbstractSuperDIB.ApplyFilter(AFilter: TDIBFilter);
var
Dest: TWinDIB;
RedAv, GreenAv, BlueAv: SmallInt;
AvModulo, MatrixOffset, LineSize, NoLines, PixelsPerLine: DWord;
Factor: Integer;
MData, SourceData, DestData: Pointer;
NewData: array[0..8] of SmallInt;
RB, GB, BB: Smallint;
begin
Dest := TWinDIB.Create(Width, Height);
LineSize := Width * 4;
NoLines := Height - 2;
PixelsPerLine := Width - 2;
AvModulo := LineSize - 12;
with AFilter do
begin
//Row 1
NewData[0] := Data[6];
NewData[1] := Data[7];
NewData[2] := Data[8];
//Row 2
NewData[3] := Data[3];
NewData[4] := Data[4];
NewData[5] := Data[5];
//Row 3
NewData[6] := Data[0];
NewData[7] := Data[1];
NewData[8] := Data[2];
end;
if AFilter.Factor > 0 then
Factor := AFilter.Factor
else
begin
Factor :=
NewData[0] + NewData[1] + NewData[2] +
NewData[3] + NewData[4] + NewData[5] +
NewData[6] + NewData[7] + NewData[8];
end;
MData := @NewData[0];
MatrixOffset := LineSize + 4;
SourceData := Pointer(DWord(FData) + MatrixOffset);
DestData := Pointer(DWord(Dest.FData) + MatrixOffset);
//Bias
RB := AFilter.RedBias;
GB := AFilter.GreenBias;
BB := AFilter.BlueBias;
asm
push ESI
push EDI
push EBX
mov ESI, SourceData
mov EDI, DestData
mov ECX, NoLines
@VLoop:
push ECX
mov ECX, PixelsPerLine
@HLoop:
call @CalcPixels
//Mask
mov al, [ESI+3]
shl EAX, 8
//Red
mov BX, RedAv
lea EAX, [EAX+EBX]
shl EAX, 8
//Green
mov BX, GreenAv
lea EAX, [EAX+EBX]
shl EAX,8
//Blue
mov BX, BlueAv
lea EAX, [EAX+EBX]
//Store the pixel color
mov [EDI], EAX
lea EDI, [EDI+4]
lea ESI, [ESI+4]
dec ECX
jnz @HLoop
lea EDI, [EDI+8]
lea ESI, [ESI+8]
pop ECX
dec ECX
jnz @VLoop
@TheEnd:
pop EBX
pop EDI
pop ESI
jmp @Exit
//==================== CALC PIXELS =========================//
@CalcPixels:
push ESI
push EDI
sub ESI, MatrixOffset
mov EDI, MData
@AvVLoop:
//==================== LINE 1 =========================//
//Pixel1
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
mov BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
mov GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
mov RedAV, AX
lea EDI,[EDI+2]
//Pixel2
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
//Pixel3
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
add ESI, AvModulo
//==================== LINE 2 =========================//
//Pixel1
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
//Pixel2
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
//Pixel3
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
add ESI, AvModulo
//==================== LINE 3 =========================//
//Pixel1
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
//Pixel2
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
lea ESI, [ESI+2]
imul bx
Add RedAv, AX
lea EDI,[EDI+2]
//Pixel3
mov bx, [EDI] //Get filter value
//BLUE
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add BlueAv, AX
//GREEN
xor EAX, EAX
mov al, [ESI] //Get pixel values
inc ESI
imul bx
Add GreenAv, AX
//RED
xor EAX, EAX
mov al, [ESI] //Get pixel values
imul bx
Add RedAv, AX
//Now add the RGBM Bias
// xor EAX, EAX
mov AX, BB
Add BlueAv, AX
mov AX, GB
Add GreenAv, AX
mov AX, RB
Add RedAv, AX
//Now divide by the factor
mov EBX, Factor
cmp EBX, 0
jz @NoDivide
//BLUE
mov AX, BlueAv
cwd
idiv BX
mov BlueAv, AX
//GREEN
mov AX, GreenAv
cwd
idiv BX
mov GreenAv, AX
//RED
mov AX, RedAv
cwd
idiv BX
mov RedAv, AX
@NoDivide:
//Put RED into 0..255 range
cmp RedAv, 255
jl @RedLT255
mov RedAv, 255
@RedLT255:
cmp RedAv, 0
jg @RedGT0
mov RedAv, 0
@RedGt0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -