mirror of
https://github.com/moparisthebest/Simba
synced 2025-02-19 20:41:48 -05:00
Finder: Start CTS rework.
This commit is contained in:
parent
a630399148
commit
6f896b56a2
@ -107,6 +107,17 @@ uses
|
|||||||
tpa, //TPABounds
|
tpa, //TPABounds
|
||||||
dtmutil;
|
dtmutil;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TCTS2Info = record
|
||||||
|
H, S, L: extended;
|
||||||
|
hueMod, satMod: extended;
|
||||||
|
end;
|
||||||
|
PCTS2Info = ^TCTS2Info;
|
||||||
|
|
||||||
|
TCTSCompareFunction = function (Tolerance: Integer; ctsInfo: Pointer; C2: PRGB32): boolean;
|
||||||
|
|
||||||
|
|
||||||
procedure TMFinder.LoadSpiralPath(startX, startY, x1, y1, x2, y2: Integer);
|
procedure TMFinder.LoadSpiralPath(startX, startY, x1, y1, x2, y2: Integer);
|
||||||
var
|
var
|
||||||
i,c,Ring : integer;
|
i,c,Ring : integer;
|
||||||
@ -328,10 +339,7 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
XXX: We should really rewrite this. Once we're adding more colour space we'll
|
TODO: Remove this
|
||||||
only be adding more and more parameters. It's really silly to push all those
|
|
||||||
args if we aren't going to use them. We need to make sure the function is
|
|
||||||
actually inlined. Because if it's not, we should go for a different design.
|
|
||||||
}
|
}
|
||||||
function ColorSame(var CTS,Tolerance : Integer; var R1,G1,B1,R2,G2,B2 : byte; var H1,S1,L1,huemod,satmod : extended) : boolean; inline;
|
function ColorSame(var CTS,Tolerance : Integer; var R1,G1,B1,R2,G2,B2 : byte; var H1,S1,L1,huemod,satmod : extended) : boolean; inline;
|
||||||
var
|
var
|
||||||
@ -357,34 +365,92 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{
|
|
||||||
TODO: See if this is actually inlined. If it is, we can shorten the
|
|
||||||
subprocedures; if it is not, either:
|
|
||||||
- Paste a lot of code.
|
|
||||||
- Pass a record of the required data to prevent pushing arguments on the
|
|
||||||
stack.
|
|
||||||
}
|
|
||||||
|
|
||||||
{ Not using var for each arg now, as it should be inlined }
|
{ Colour Same functions }
|
||||||
function ColorSame_cts0(Tolerance : Integer; R1,G1,B1,R2,G2,B2 : byte) : boolean; inline;
|
function ColorSame_cts0(Tolerance: Integer; ctsInfo: Pointer; C2: PRGB32): boolean;
|
||||||
|
|
||||||
|
var
|
||||||
|
C1: TRGB32;
|
||||||
begin
|
begin
|
||||||
Result := ((Abs(R1-R2) <= Tolerance) and (Abs(G1-G2) <= Tolerance) and (Abs(B1-B2) <= Tolerance));
|
C1 := PRGB32(ctsInfo)^;
|
||||||
|
Result := (Abs(C1.B - C2^.B) <= Tolerance)
|
||||||
|
and (Abs(C1.G - C2^.G) <= Tolerance)
|
||||||
|
and (Abs(C1.R - C2^.R) <= Tolerance);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Not using var for each arg now, as it should be inlined }
|
function ColorSame_cts1(ToleranceSqr: Integer; ctsInfo: Pointer; C2: PRGB32): boolean;
|
||||||
function ColorSame_cts1(Tolerance : Integer; R1,G1,B1,R2,G2,B2 : byte) : boolean; inline;
|
|
||||||
|
|
||||||
|
var
|
||||||
|
C1: TRGB32;
|
||||||
|
r,g,b: integer;
|
||||||
begin
|
begin
|
||||||
Result := (Sqrt(sqr(R1-R2) + sqr(G1-G2) + sqr(B1-B2)) <= Tolerance);
|
C1 := PRGB32(ctsInfo)^;
|
||||||
|
b := C1.B - C2^.B;
|
||||||
|
b := b * b;
|
||||||
|
g := C1.G - C2^.G;
|
||||||
|
g := g * g;
|
||||||
|
r := C1.R - C2^.R;
|
||||||
|
r := r * r;
|
||||||
|
Result := (b + g + r) < ToleranceSqr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ColorSame_cts2(Tolerance: Integer; H1, S1, L1, H2,S2,L2, hueMod, satMod: extended):
|
function ColorSame_cts2(Tolerance: Integer; ctsInfo: Pointer; C2: PRGB32): boolean;
|
||||||
boolean; inline;
|
|
||||||
|
var
|
||||||
|
h, s, l: extended;
|
||||||
|
i: TCTS2Info;
|
||||||
begin
|
begin
|
||||||
result := ((abs(H1 - H2) <= (hueMod * Tolerance)) and
|
i := PCTS2Info(ctsInfo)^;
|
||||||
(abs(S1 - S2) <= (satMod * Tolerance))
|
RGBToHSL(C2^.R, C2^.G, C2^.B, h, s, l); // Inline this later.
|
||||||
and (abs(L1 - L2) <= Tolerance));
|
|
||||||
|
Result := (abs(h - i.H) <= (i.hueMod * Tolerance))
|
||||||
|
and (abs(s - i.S) <= (i.satMod * Tolerance))
|
||||||
|
and (abs(l - i.L) <= Tolerance);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ }
|
||||||
|
|
||||||
|
function Create_CTSInfo(cts: integer; Color, Tol: Integer;
|
||||||
|
hueMod, satMod: extended): Pointer;
|
||||||
|
var
|
||||||
|
R, G, B: Integer;
|
||||||
|
H, S, L: Integer;
|
||||||
|
begin
|
||||||
|
case cts of
|
||||||
|
0, 1:
|
||||||
|
begin
|
||||||
|
Result := AllocMem(SizeOf(TRGB32));
|
||||||
|
ColorToRGB(Color, PRGB32(Result)^.R, PRGB32(Result)^.G,
|
||||||
|
PRGB32(Result)^.B);
|
||||||
|
end;
|
||||||
|
2:
|
||||||
|
begin
|
||||||
|
Result := AllocMem(SizeOf(TRGB32));
|
||||||
|
ColorToRGB(Color, R, G, B);
|
||||||
|
RGBToHSL(R, G, B, PCTS2Info(Result)^.H, PCTS2Info(Result)^.S,
|
||||||
|
PCTS2Info(Result)^.L);
|
||||||
|
PCTS2Info(Result)^.hueMod := Tol * hueMod;
|
||||||
|
PCTS2Info(Result)^.satMod := Tol * satMod;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Free_CTSInfo(i: Pointer);
|
||||||
|
begin
|
||||||
|
if assigned(i) then
|
||||||
|
FreeMem(i)
|
||||||
|
else
|
||||||
|
raise Exception.Create('Free_CTSInfo: Invalid TCTSInfo passed');
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Get_CTSCompare(cts: Integer): TCTSCompareFunction;
|
||||||
|
|
||||||
|
begin
|
||||||
|
case cts of
|
||||||
|
0: Result := @ColorSame_cts0;
|
||||||
|
1: Result := @ColorSame_cts1;
|
||||||
|
2: Result := @ColorSame_cts2;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMFinder.UpdateCachedValues(NewWidth, NewHeight: integer);
|
procedure TMFinder.UpdateCachedValues(NewWidth, NewHeight: integer);
|
||||||
@ -1107,25 +1173,9 @@ var
|
|||||||
PtrInc,C: Integer;
|
PtrInc,C: Integer;
|
||||||
dX, dY, clR, clG, clB: Integer;
|
dX, dY, clR, clG, clB: Integer;
|
||||||
|
|
||||||
procedure cts0;
|
xx, yy: integer;
|
||||||
var xx, yy: integer;
|
compare: TCTSCompareFunction;
|
||||||
begin
|
ctsinfo: Pointer;
|
||||||
for yy := ys to ye do
|
|
||||||
begin
|
|
||||||
for xx := xs to xe do
|
|
||||||
begin
|
|
||||||
if ((abs(clB-Ptr^.B) <= Tol) and (abs(clG-Ptr^.G) <= Tol) and (Abs(clR-Ptr^.R) <= Tol)) then
|
|
||||||
begin
|
|
||||||
ClientTPA[c].x := xx;
|
|
||||||
ClientTPA[c].y := yy;
|
|
||||||
inc(c);
|
|
||||||
end;
|
|
||||||
inc(Ptr);
|
|
||||||
end;
|
|
||||||
Inc(Ptr, PtrInc);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure cts1;
|
procedure cts1;
|
||||||
var xx, yy: integer;
|
var xx, yy: integer;
|
||||||
@ -1170,9 +1220,7 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure cts3;
|
{ procedure cts3;
|
||||||
var xx, yy: integer;
|
|
||||||
L1, A1, B1, L2, A2, B2, X, Y, Z: extended;
|
|
||||||
begin
|
begin
|
||||||
RGBToXYZ(clR, clG, clB, X, Y, Z);
|
RGBToXYZ(clR, clG, clB, X, Y, Z);
|
||||||
XYZToCieLab(X, Y, Z, L1, A1, B1);
|
XYZToCieLab(X, Y, Z, L1, A1, B1);
|
||||||
@ -1193,7 +1241,7 @@ var
|
|||||||
end;
|
end;
|
||||||
Inc(Ptr, PtrInc);
|
Inc(Ptr, PtrInc);
|
||||||
end;
|
end;
|
||||||
end;
|
end; }
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
@ -1201,8 +1249,6 @@ begin
|
|||||||
|
|
||||||
dX := xe - xs;
|
dX := xe - xs;
|
||||||
dY := ye - ys;
|
dY := ye - ys;
|
||||||
//next, convert the color to r,g,b
|
|
||||||
ColorToRGB(Color, clR, clG, clB);
|
|
||||||
|
|
||||||
PtrData := TClient(Client).IOManager.ReturnData(xs, ys, dX + 1, dY + 1);
|
PtrData := TClient(Client).IOManager.ReturnData(xs, ys, dX + 1, dY + 1);
|
||||||
|
|
||||||
@ -1211,16 +1257,30 @@ begin
|
|||||||
Ptr := PtrData.Ptr;
|
Ptr := PtrData.Ptr;
|
||||||
PtrInc := PtrData.IncPtrWith;
|
PtrInc := PtrData.IncPtrWith;
|
||||||
c := 0;
|
c := 0;
|
||||||
case CTS of
|
|
||||||
0: cts0();
|
ctsinfo := Create_CTSInfo(Self.CTS, Color, Tol, hueMod, satMod);
|
||||||
1: cts1();
|
compare := Get_CTSCompare(Self.CTS);
|
||||||
2: cts2();
|
|
||||||
3: cts3();
|
for yy := ys to ye do
|
||||||
|
begin
|
||||||
|
for xx := xs to xe do
|
||||||
|
begin
|
||||||
|
if compare(Tol, ctsinfo, Ptr) then
|
||||||
|
begin
|
||||||
|
ClientTPA[c].x := xx;
|
||||||
|
ClientTPA[c].y := yy;
|
||||||
|
inc(c);
|
||||||
|
end;
|
||||||
|
inc(Ptr);
|
||||||
|
end;
|
||||||
|
Inc(Ptr, PtrInc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
SetLength(Points, C);
|
SetLength(Points, C);
|
||||||
Move(ClientTPA[0], Points[0], C * SizeOf(TPoint));
|
Move(ClientTPA[0], Points[0], C * SizeOf(TPoint));
|
||||||
Result := C > 0;
|
Result := C > 0;
|
||||||
TClient(Client).IOManager.FreeReturnData;
|
TClient(Client).IOManager.FreeReturnData;
|
||||||
|
Free_CTSInfo(ctsinfo)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMFinder.FindColorsToleranceOptimised(out Points: TPointArray; Color, xs, ys,
|
function TMFinder.FindColorsToleranceOptimised(out Points: TPointArray; Color, xs, ys,
|
||||||
@ -1641,111 +1701,28 @@ begin
|
|||||||
TClient(Client).IOManager.FreeReturnData;
|
TClient(Client).IOManager.FreeReturnData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
TODO: Implement HSLRows?
|
||||||
|
}
|
||||||
function TMFinder.FindBitmapToleranceIn(bitmap: TMufasaBitmap; out x, y: Integer; xs,
|
function TMFinder.FindBitmapToleranceIn(bitmap: TMufasaBitmap; out x, y: Integer; xs,
|
||||||
ys, xe, ye: Integer; tolerance: Integer): Boolean;
|
ys, xe, ye: Integer; tolerance: Integer): Boolean;
|
||||||
var
|
var
|
||||||
MainRowdata : TPRGB32Array;
|
MainRowdata : TPRGB32Array;
|
||||||
PtrData : TRetData;
|
BmpRowData : TPRGB32Array;
|
||||||
BmpW,BmpH : integer;
|
PtrData : TRetData;
|
||||||
dX, dY: Integer;
|
BmpW,BmpH : integer;
|
||||||
SkipCoords : T2DBoolArray;
|
xBmp,yBmp : integer;
|
||||||
foundP: TPoint;
|
tmpY : integer;
|
||||||
|
dX, dY, xx, yy: Integer;
|
||||||
function cts0: tpoint;
|
CCTS : integer;
|
||||||
var xx, yy, xBmp, yBmp, tmpY: integer;
|
H,S,L,HMod,SMod : extended;
|
||||||
BmpRowData : TPRGB32Array;
|
SkipCoords : T2DBoolArray;
|
||||||
label NotFoundBmp;
|
label NotFoundBmp;
|
||||||
begin
|
|
||||||
BmpRowData:= CalculateRowPtrs(bitmap);
|
|
||||||
|
|
||||||
for yy := 0 to dY do
|
|
||||||
for xx := 0 to dX do
|
|
||||||
begin
|
|
||||||
for yBmp:= 0 to BmpH do
|
|
||||||
begin
|
|
||||||
tmpY := yBmp + yy;
|
|
||||||
for xBmp := 0 to BmpW do
|
|
||||||
if not SkipCoords[yBmp][xBmp] then
|
|
||||||
if not ColorSame_cts0(Tolerance,
|
|
||||||
BmpRowData[yBmp][xBmp].R,BmpRowData[yBmp][xBmp].G,BmpRowData[yBmp][xBmp].B,
|
|
||||||
MainRowdata[tmpY][xBmp + xx].R,
|
|
||||||
MainRowdata[tmpY][xBmp + xx].G,MainRowdata[tmpY][xBmp + xx].B) then
|
|
||||||
goto NotFoundBmp;
|
|
||||||
end;
|
|
||||||
exit(Point(xx + xs, yy + ys));
|
|
||||||
NotFoundBmp: // double break
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := Point(-1, -1);
|
|
||||||
end;
|
|
||||||
{ Don't know if the compiler has any speed-troubles with goto jumping in nested for loops. }
|
{ Don't know if the compiler has any speed-troubles with goto jumping in nested for loops. }
|
||||||
|
|
||||||
function cts1: tpoint;
|
|
||||||
var xx, yy, xBmp, yBmp, tmpY: integer;
|
|
||||||
BmpRowData : TPRGB32Array;
|
|
||||||
label NotFoundBmp;
|
|
||||||
begin
|
|
||||||
BmpRowData:= CalculateRowPtrs(bitmap);
|
|
||||||
|
|
||||||
for yy := 0 to dY do
|
|
||||||
for xx := 0 to dX do
|
|
||||||
begin
|
|
||||||
for yBmp:= 0 to BmpH do
|
|
||||||
begin
|
|
||||||
tmpY := yBmp + yy;
|
|
||||||
for xBmp := 0 to BmpW do
|
|
||||||
if not SkipCoords[yBmp][xBmp] then
|
|
||||||
if not ColorSame_cts1(Tolerance,
|
|
||||||
BmpRowData[yBmp][xBmp].R,BmpRowData[yBmp][xBmp].G,BmpRowData[yBmp][xBmp].B,
|
|
||||||
MainRowdata[tmpY][xBmp + xx].R,
|
|
||||||
MainRowdata[tmpY][xBmp + xx].G,MainRowdata[tmpY][xBmp + xx].B) then
|
|
||||||
goto NotFoundBmp;
|
|
||||||
end;
|
|
||||||
exit(Point(xx + xs, yy + ys));
|
|
||||||
NotFoundBmp: // double break
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := Point(-1, -1);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function cts2: tpoint;
|
|
||||||
var H2, S2, L2, HMod, SMod: extended;
|
|
||||||
xx, yy, xBmp, yBmp, tmpY: integer;
|
|
||||||
|
|
||||||
HSLRows: T2DHSLArray;
|
|
||||||
|
|
||||||
label NotFoundBmp;
|
|
||||||
begin
|
|
||||||
HSLRows := bitmap.GetHSLValues(0, 0, BmpW, BmpH);
|
|
||||||
|
|
||||||
for yy := 0 to dY do
|
|
||||||
for xx := 0 to dX do
|
|
||||||
begin
|
|
||||||
for yBmp:= 0 to BmpH do
|
|
||||||
begin
|
|
||||||
tmpY := yBmp + yy;
|
|
||||||
for xBmp := 0 to BmpW do
|
|
||||||
if not SkipCoords[yBmp][xBmp] then
|
|
||||||
begin
|
|
||||||
RGBToHSL(MainRowdata[tmpY][xBmp + xx].R, MainRowdata[tmpY][xBmp + xx].G,
|
|
||||||
MainRowdata[tmpY][xBmp + xx].B, H2, S2, L2);
|
|
||||||
|
|
||||||
if not ColorSame_cts2(Tolerance, HSLRows[yBmp][xBmp].H,
|
|
||||||
HSLRows[yBmp][xBmp].S, HSLRows[yBmp][xBmp].L,
|
|
||||||
//if not ColorSame_cts2(Tolerance, HSLRows[yBmp][xBmp].H, HSLRows[yBmp][xBmp].S, HSLRows[yBmp][xBmp].L,
|
|
||||||
H2, S2, L2, hueMod, satMod) then
|
|
||||||
goto NotFoundBmp;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
exit(Point(xx + xs, yy + ys));
|
|
||||||
NotFoundBmp: // double break
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result := Point(-1, -1);
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := false;
|
||||||
// checks for valid xs,ys,xe,ye? (may involve GetDimensions)
|
// checks for valid xs,ys,xe,ye? (may involve GetDimensions)
|
||||||
DefaultOperations(xs,ys,xe,ye);
|
DefaultOperations(xs,ys,xe,ye);
|
||||||
|
|
||||||
@ -1756,31 +1733,43 @@ begin
|
|||||||
PtrData := TClient(Client).IOManager.ReturnData(xs, ys, dX + 1, dY + 1);
|
PtrData := TClient(Client).IOManager.ReturnData(xs, ys, dX + 1, dY + 1);
|
||||||
//Caculate the row ptrs
|
//Caculate the row ptrs
|
||||||
MainRowdata:= CalculateRowPtrs(PtrData,dy+1);
|
MainRowdata:= CalculateRowPtrs(PtrData,dy+1);
|
||||||
|
BmpRowData:= CalculateRowPtrs(bitmap);
|
||||||
|
|
||||||
//Get the 'fixed' bmp size
|
//Get the 'fixed' bmp size
|
||||||
BmpW := bitmap.Width - 1;
|
BmpW := bitmap.Width - 1;
|
||||||
BmpH := bitmap.Height - 1;
|
BmpH := bitmap.Height - 1;
|
||||||
//Heck our bitmap cannot be outside the search area
|
//Heck our bitmap cannot be outside the search area
|
||||||
dX := dX - bmpW;
|
dX := dX - bmpW;
|
||||||
dY := dY - bmpH;
|
dY := dY - bmpH;
|
||||||
|
//Compiler hints
|
||||||
|
HMod := 0;SMod := 0;H := 0.0;S := 0.0; L := 0.0;
|
||||||
|
|
||||||
|
CCTS := Self.CTS;
|
||||||
|
|
||||||
//Get the "skip coords".
|
//Get the "skip coords".
|
||||||
CalculateBitmapSkipCoords(Bitmap,SkipCoords);
|
CalculateBitmapSkipCoords(Bitmap,SkipCoords);
|
||||||
|
for yy := 0 to dY do
|
||||||
|
for xx := 0 to dX do
|
||||||
|
begin;
|
||||||
|
for yBmp:= 0 to BmpH do
|
||||||
|
begin;
|
||||||
|
tmpY := yBmp + yy;
|
||||||
|
for xBmp := 0 to BmpW do
|
||||||
|
if not SkipCoords[yBmp][xBmp] then
|
||||||
|
if not ColorSame(CCTS,tolerance,
|
||||||
|
BmpRowData[yBmp][xBmp].R,BmpRowData[yBmp][xBmp].G,BmpRowData[yBmp][xBmp].B,
|
||||||
|
MainRowdata[tmpY][xBmp + xx].R,MainRowdata[tmpY][xBmp + xx].G,MainRowdata[tmpY][xBmp + xx].B,
|
||||||
|
H,S,L,HMod,SMod) then
|
||||||
|
goto NotFoundBmp;
|
||||||
|
|
||||||
case Self.CTS of
|
end;
|
||||||
0: foundP := cts0();
|
//We did find the Bmp, otherwise we would be at the part below
|
||||||
1: foundP := cts1();
|
TClient(Client).IOManager.FreeReturnData;
|
||||||
2: foundP := cts2();
|
x := xx + xs;
|
||||||
end;
|
y := yy + ys;
|
||||||
|
result := true;
|
||||||
if (foundP.x = -1) and (foundP.y = -1) then
|
exit;
|
||||||
result := False
|
NotFoundBmp:
|
||||||
else begin
|
end;
|
||||||
x := foundP.x;
|
|
||||||
y := foundP.y;
|
|
||||||
Result := True;
|
|
||||||
end;
|
|
||||||
TClient(Client).IOManager.FreeReturnData;
|
TClient(Client).IOManager.FreeReturnData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user