那位大侠帮我把这段c++汇编翻译成delphi(100分)

  • 主题发起人 hitman007260
  • 开始时间
H

hitman007260

Unregistered / Unconfirmed
GUEST, unregistred user!
const int __idecimal = 4096;
inline int AverageResize32VergeLine(BYTE * p_out,BYTE * p_in1,BYTE * p_in2,int x_verge,int x_in2,int x_delta)
{
//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
}
return x_in2;
}
void AverageResize32Line(BYTE * p_out,BYTE * p_in1,BYTE * p_in2,int x_verge,int out_width,int x_in2,int x_delta)
{
//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:
#ifdo
UBLE_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:
}
}
unsigned int AverageResize32(void * out,int out_width,int out_height,int out_pitch,
const void * in,int in_width,int in_height,int in_pitch)
{
//边界值
int y_delta = __idecimal * in_height / out_height;
int x_delta = __idecimal * in_width / out_width;
int y_verge = in_height / out_height / 2;
int x_verge = in_width / out_width / 2;
BYTE * p_out = (BYTE *)out;
int y_in2 = y_delta / 2;
//y边界条件
BYTE * p_in1 = (BYTE *)in;
BYTE * p_in2 = (BYTE *)((int)in + in_pitch * (y_in2 / __idecimal));
for(int y_out=0;
y_out<y_verge;
++y_out)
{
//y,x边界条件
int x_in2 = x_delta / 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 = (BYTE *)((int)p_out + out_pitch);
y_in2 += y_delta;
p_in2 = (BYTE *)((int)p_in2 + in_pitch * (y_in2 / __idecimal));
y_in2 %= __idecimal;
}
p_in1 = (BYTE *)((int)in + in_pitch * ((y_delta * y_out - y_delta / 2) / __idecimal));
p_in2 = (BYTE *)((int)in + in_pitch * ((y_delta * y_out + y_delta / 2) / __idecimal));
for(;
y_out<out_height;
++y_out)
{
//x边界条件
int x_in2 = x_delta / 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 = (BYTE *)((int)p_out + out_pitch);
y_in2 += y_delta;
p_in1 = p_in2;
//p_in1 = (BYTE *)((int)p_in1 + in_pitch * (y_in2 / __idecimal));
p_in2 = (BYTE *)((int)p_in2 + in_pitch * (y_in2 / __idecimal));
y_in2 %= __idecimal;
}
__asm emms;
return 0;
}
 
先来第一个函数:(不知道错了没,汇编部分没有动过)
const __idecimal = 4096;
function AverageResize32VergeLine(var 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;
 
p_in2:^BYTE
指针报错
 
第二个函数和第一差不多,自己对着改吧。这是最后一个
依然是没测试过的,这两天Delphi有点问题,要重装....所以你自己数进去看看哪错了吧。
function AverageResize32(var out:Variant;out_width,out_height,out_pitch:integer;
const in:^Variant;in_width,in_height,in_pitch:integer):cardinal;
var
x_delta, y_delta, x_verge, y_verge, x_in2, y_in2, y_out: Integer;
p_out,p_in1,p_in2: ^BYTE;
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;
p_out := BYTE(out);
//这样做显然不可能,要其他方式将数据转为BYTE指针
y_in2 := y_delta div 2;
//y边界条件
p_in1 = BYTE(in);
//这里和上面一样...
p_in2 = BYTE((Integer(in) + in_pitch * (y_in2 div __idecimal)));
for y_out:=0 to y_verge-1do
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 := BYTE((Integer(p_out) + out_pitch));
y_in2 := y_in2+y_delta;
p_in2 = BYTE((Integer(p_in2) + in_pitch * (y_in2 div __idecimal)));
y_in2 = y_in2 mod __idecimal;
}
p_in1 := BYTE((Integer(in) + in_pitch * ((y_delta * y_out - y_delta div 2) div __idecimal)));
p_in2 := BYTE((Integer(in) + in_pitch * ((y_delta * y_out + y_delta div 2) div __idecimal));
while (y_out<out_height)do
begin
inc(y_out);
//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 := BYTE((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 = BYTE((Integer(p_in2) + in_pitch * (y_in2 div __idecimal)));
y_in2 = y_in2 mod __idecimal;
end;
 
想了一下,既然
p_out := BYTE(out);
//这样做显然不可能,要其他方式将数据转为BYTE指针
那么就换成直接取地址算了: p_out:=@out;
那个指针类型定义因该没问题啊,你看看是不是其他地方出错了
再不行换成Pointer型指针试试。
 
^byte换成 Pointer 可以
但是 ja __end
汇编报错
 
把行标换成 @@end 试试
就是把所有的 __end 替换为 @@end 看看,我记得好像是@@来者。
ja @@end
...
@@end
...
 
第二个函数的 汇编部分的#ifdo
UBLE_AVERAGE
mov eax,ebx
报错
 
大侠不在了吗?
 
#ifdo
UBLE_AVERAGE
...
#else
...
#endif
拆出来写,这不是ASM的标记。即放到asm外面:
...
ifdo
UBLE_AVERAGE then
asm
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
end
else
asm
...//照搬#else
里的
end;
 
真对不起 我太菜了
if 得上面是@@loop:
还是不行
麻烦你了
 
确实,看了一下,不能拆出来写。这样写第二段(我把它改成汇编了):
procedure AverageResize32Line(var 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:
//原来的 #ifdo
UBLE_AVERAGE 改成下面两行:
testdo
UBLE_AVERAGE,True //检查do
UBLE_AVERAGE 是否为True
jz @@else
//不为True,跳向@@else

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
jmp @@endif //这里加个跳转
@@else
: //原来的#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: //#endif 改成行标
movd dword ptr[edi + ecx * 4 + 0],mm0
add ebx,x_delta
inc ecx
cmp ecx,out_width
jb @@loop
@@end:
end;
end;
 
第三个函数这里有错误:
const in:^Variant
^byte换成 Pointer 后第三个函数
p_in2:= BYTE((Integer(in) + in_pitch * (y_in2 div __idecimal)));
也报错;
 
我只想将一个图片快速缩放而已stretchbit和drawdibdraw太慢了
没有人帮我翻译一下这个程序吗??
 
^Byte,肯定要报错, -->PByte,
p_int1, p_in2都是指针类型, 在赋值的时候, 要注意类型匹配.
这样
-----
p_in2 := Pointer( BYTE((Integer(p_in2) + in_pitch * (y_in2 div __idecimal))) );
 
PByte的原型就是^Byte,你可以按Ctrl跟踪一下,所以如果^byte通过不了,Pbyte也不行
确实如楼上所说,指针变量要转化,可以用Pointer()强制转型,好像也能直接用取址符 @
p_in2:=@BYTE((Integer(in) + in_pitch * (y_in2 div __idecimal)));
试试
const in:^Variant 因该也是像^Byte一样的问题,PVariant和Pointer都试试吧,再不行就得改内部代码了
 
Variant
pVariant 如何用?
怎样把bitmap输入和导出?
 
pVariant 就是 Variant类型的指针,和^Variant是一个意思。用Pointer也能代替PVariant
bitmap输入和导出
用TBitmap类,声明一个 var bmp1:TBitmap;
然后 bmp1.LoadFormFile('xxx');
//好像是LoadFormFile,可以直接读写文件
最后 SaveTo...
要修改的话,直接对bmp1.Canvas操作
 

我的意思是如何把要缩放的bitmap做为参数传递给function AverageResize32(var out:Variant;out_width,out_height,out_pitch:integer;
const in:^Variant;in_width,in_height,in_pitch:integer):cardinal;
就是如何把Tbitmap转为VARIANT然后把^variant转化为bitmap;
 
或者jpeg也可以
 
顶部