哪里缩放的原理呀?看源码看的很累人,还可能有误解。希望哪位给出来!
To:hitman007260 C++源码我已经改出来了,但没用去试验正确以否,因为C++改过的指针在DELPHI中不是那么好用。
-------------------------------------------
var
__idecimal:integer = 4096
function AverageResize32VergeLine(p_out,p_in1,p_in2
Byte;x_verge,x_in2,x_delta:integer):integer;
begin
//ebx : x_in2
//ecx : x_out
//edi : p_out
//esi : p_in1
//edx : p_in2
asm
xor ecx,ecx
cmp ecx,x_verge
ja @__end
mov edi,p_out
mov esi,p_in1
mov edx,p_in2
mov ebx,x_in2
@__loop:
mov eax,ebx
shr eax,12
movd mm0,dword ptr [esi + eax * 4 + 0]
movd mm3,dword ptr [edx + eax * 4 + 0]
punpcklbw mm0,mm0
punpcklbw mm3,mm3
psrlw mm0,8
psrlw mm3,8
paddw mm0,mm3
psrlw mm0,1
packuswb mm0,mm0
movd dword ptr[edi + ecx * 4 + 0],mm0
add ebx,x_delta
inc ecx
cmp ecx,x_verge
jbe @__loop
@__end:
mov x_in2,ebx
end;
Result:= x_in2;
end;
procedure AverageResize32Line(p_out,p_in1,p_in2
Byte;
x_verge,out_width,x_in2,x_delta:integer);
begin
//ebx : x_in2
//ecx : x_out
//edi : p_out
//esi : p_in1
//edx : p_in2
asm
mov ecx,x_verge
cmp ecx,out_width
jae @__end
mov edi,p_out
mov esi,p_in1
mov edx,p_in2
mov ebx,x_in2
@__loop:
//#if DOUBLE_AVERAGE
mov eax,ebx
sub eax,x_delta
shr eax,12
movd mm0,dword ptr [esi + eax * 4 + 0]
movd mm1,dword ptr [edx + eax * 4 + 0]
mov eax,ebx
shr eax,12
movd mm2,dword ptr [esi + eax * 4 + 0]
movd mm3,dword ptr [edx + eax * 4 + 0]
punpcklbw mm0,mm0
punpcklbw mm1,mm1
punpcklbw mm2,mm2
punpcklbw mm3,mm3
psrlw mm0,8
psrlw mm1,8
psrlw mm2,8
psrlw mm3,8
paddw mm2,mm3
paddw mm0,mm1
paddw mm0,mm2
psrlw mm0,2
packuswb mm0,mm0
//#else
mov eax,ebx
sub eax,x_delta
shr eax,12
movd mm0,dword ptr [esi + eax * 4 + 0]
mov eax,ebx
shr eax,12
movd mm3,dword ptr [edx + eax * 4 + 0]
punpcklbw mm0,mm0
punpcklbw mm3,mm3
psrlw mm0,8
psrlw mm3,8
paddw mm0,mm3
psrlw mm0,1
packuswb mm0,mm0
//#endif
movd dword ptr[edi + ecx * 4 + 0],mm0
add ebx,x_delta
inc ecx
cmp ecx,out_width
jb @__loop
@__end:
end;
end;
function AverageResize32(Pout
ointer;out_width,out_height,out_pitch:integer;
const Pin
ointer;in_width,in_height,in_pitch:integer):integer;
var
y_delta,x_delta,y_verge,x_verge:integer;
p_out
Byte;
y_in2,x_in2:integer;
p_in1,p_in2
Byte;
y_out:integer;
begin
//边界值
y_delta := (__idecimal * in_height) div out_height;
x_delta := (__idecimal * in_width) div out_width;
y_verge := (in_height div out_height) div 2;
x_verge := (in_width div out_width) div 2;
// BYTE * p_out = (BYTE *)out;
p_out := PByte(Pout);
y_in2 := y_delta div 2;
//y边界条件
p_in1 := Pbyte(Pin);
p_in2 := PByte(integer(Pin) + in_pitch * (y_in2 div __idecimal));
for y_out:=0 to y_verge-1 do begin
//y,x边界条件
x_in2 := x_delta div 2;
x_in2 := AverageResize32VergeLine(p_out,p_in1,p_in2,x_verge,x_in2,x_delta);
AverageResize32Line(p_out,p_in1,p_in2,x_verge,out_width,x_in2,x_delta);
p_out := PByte(integer(p_out) + out_pitch);
y_in2 := y_in2+y_delta;
p_in2 := PByte(integer(p_in2) + in_pitch * (y_in2 div __idecimal));
y_in2 := y_in2 xor __idecimal; // ??????? %= 与
end;
p_in1 := PByte(Integer(Pin) + in_pitch * ((y_delta * y_out - y_delta div 2) div __idecimal));
p_in2 := PByte(Integer(Pin) + in_pitch * ((y_delta * y_out + y_delta div 2) div __idecimal));
for y_out:=y_verge-1 to out_height-1 do begin
//x边界条件
x_in2 := x_delta div 2;
x_in2 := AverageResize32VergeLine(p_out,p_in1,p_in2,x_verge,x_in2,x_delta);
AverageResize32Line(p_out,p_in1,p_in2,x_verge,out_width,x_in2,x_delta);
p_out := PByte(integer(p_out) + out_pitch);
y_in2 := y_in2+y_delta;
p_in1 := p_in2;
//p_in1 = (BYTE *)((int)p_in1 + in_pitch * (y_in2 / __idecimal));
p_in2 := PByte(Integer(p_in2) + in_pitch * (y_in2 div __idecimal));
y_in2 := y_in2 xor __idecimal;
end;
asm
emms;
end;
result := 0;
end;