这个有一个比较图像的简单方案:用scanline得到行指针,然后给你提供一个函数来比较行的差别,是用MMX指令优化过的。
function GetDataDifferenceMMX(SData:array of pbyteArray;Sx0,Sy0,Width,Height:integer;
TData:array of pbyteArray;Tx0,Ty0:integer):integer;
var
i,j : integer;
Ps,pt : pbyteArray;
width8 : integer;
width8sub24 : integer;
width24 : integer;
begin
result:=0;
width8:=(width div 8);
width24:=(width div 24);
width8sub24:=width8-width24*3;
if width24>0 then
begin
for i:=0 to Height -1 do
begin
ps:= Pointer(integer(Sdata[i+Sy0])+Sx0);
pt:= Pointer(integer(TData[i+Ty0])+Tx0);
asm
push ebx
push esi
push edi
xor eax,eax
mov esi,ps
mov edi,pt
pxor mm3,mm3
mov ecx,width24
@@StartFor:
//{按24字节边界对齐处理
movq mm0,[esi]
movq mm1,[edi]
movq mm2,mm0
psubusb mm0,mm1
psubusb mm1,mm2
por mm0,mm1
movq mm4,[esi+8]
movq mm5,[edi+8]
movq mm2,mm4
psubusb mm4,mm5
psubusb mm5,mm2
por mm4,mm5
movq mm6,[esi+16]
movq mm7,[edi+16]
movq mm2,mm6
psubusb mm6,mm7
psubusb mm7,mm2
por mm6,mm7
//add all
movq mm1,mm0
punpcklbw mm0,mm3
punpckhbw mm1,mm3
pmaddwd mm0,mm0
pmaddwd mm1,mm1
paddd mm0,mm1
movq mm5,mm4
punpcklbw mm4,mm3
punpckhbw mm5,mm3
pmaddwd mm4,mm4
pmaddwd mm5,mm5
paddd mm4,mm5
movq mm7,mm6
punpcklbw mm6,mm3
punpckhbw mm7,mm3
pmaddwd mm6,mm6
pmaddwd mm7,mm7
paddd mm6,mm7
//
paddd mm0,mm4
paddd mm0,mm6
movd edx,mm0
punpckhdq mm0,mm3
add eax,edx
movd ebx,mm0
add eax,ebx
add esi,24
add edi,24
//}
dec ecx
jnz @@StartFor
@@EndFor:
add result,eax
pop edi
pop esi
pop ebx
end;
end;
end;
//(*
if width8sub24>0 then
begin
for i:=0 to Height -1 do
begin
ps:= Pointer(integer(Sdata[i+Sy0])+Sx0+width24*24);
pt:= Pointer(integer(TData[i+Ty0])+Tx0+width24*24);
asm
push ebx
push esi
push edi
xor eax,eax
mov esi,ps
mov edi,pt
pxor mm3,mm3
mov ecx,width8sub24
@@StartFor:
//{按8字节边界对齐处理
movq mm0,[esi]
movq mm1,[edi]
//abs(a-b)
movq mm2,mm0
psubusb mm0,mm1
psubusb mm1,mm2
por mm0,mm1
//add all
movq mm1,mm0
punpcklbw mm0,mm3
punpckhbw mm1,mm3
pmaddwd mm0,mm0
pmaddwd mm1,mm1
paddd mm0,mm1
movd edx,mm0
punpckhdq mm0,mm3
add eax,edx
movd ebx,mm0
add eax,ebx
add esi,8
add edi,8
//}
dec ecx
jnz @@StartFor
@@EndFor:
add result,eax
pop edi
pop esi
pop ebx
end;
end;
//*)
end;
if width8*8<width then
begin
for i:=0 to Height -1 do
begin
ps:= Pointer(integer(Sdata[i+Sy0])+Sx0);
pt:= Pointer(integer(TData[i+Ty0])+Tx0);
for j:=width8*8 to Width -1 do
begin
result:=result+(sqr(ps[j]-pt[j]));
end;
end;
end;
asm
emms //
end;
//MMX处理结束
end;