请问高手这个函数如何调用 ( 积分: 50 )

  • 主题发起人 主题发起人 冬月
  • 开始时间 开始时间

冬月

Unregistered / Unconfirmed
GUEST, unregistred user!
在硬盘有AAA。PAK这样一个文件,有如下一个函数,如何调用?
procedure UnPak(PakOffSet,ESize,DSize:integer;SMem:TMemoryStream;DestFileName:String);
var
DMem,TempMem:TMemoryStream;
i:integer;
Buf1:Byte;
Ti,Tdi,Di,Tteax,Ttesi,Ttedx,Ttebp,Ttedi,Ttesp14:integer;
begin
DMem:=TMemoryStream.Create;//目标文件流
TempMem:=TMemoryStream.Create;//临时流
TempMem.SetSize(ESize);//指定临时流大小为压缩大小
DMem.SetSize(DSize);//指定目标流大小为解压缩大小
SMem.position:=PakOffSet;//指定偏移;
TempMem.CopyFrom(SMem,Esize);//从PAK文件流指定偏移读取压缩大小内存块到临时流
//在这里进行处理,把TempMem的内存流处理后写入DMem
Tteax:=0;
Ttesp14:=1;
Ti:=0;
Di:=0;
//--------------------------------- 第一阶段
repeat
if (lo(Tteax) and $7F =0) then //取Tteax的低位与 $7F进行 and运算
begin //如果=0的话就取压缩文件的第一字节FF进行赋予Tteax
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
Tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax
//如果不=0的话tteax就象加也就是说*2
TempMem.position:=Ti
//这里是正常的读取文件,边读边写
TempMem.Read(buf1,1);
DMem.position:=Di;
DMem.write(buf1,1);
Ti:=Ti+1;
Di:=Di+1;
until hi(tteax) and $01 =0
//比较Tteax的高位与 $01 进行 AND运算结果=的话就进入第二阶段
//---------------------------------
Ttesi:=$01
//第二阶段,先给Ttesi赋予1
repeat
if (lo(tteax) and $7F =0) then //对Tteax与 $7F 进行AND运算,结果为0时就读取文件赋予Tteax
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax
//运算结果不为0话就相加
ttedx:=tteax
//Tteax的值传给Ttedx
ttedx:=ttedx shr 8
//Ttedx经过右移运算,AND运算
ttedx:=ttedx and 1;
ttesi:=ttesi*2+ttedx
//Ttesi的值等于Ttesi*2+上面Ttedx运算完毕的值
if (lo(tteax) and $7F =0) then //Tteax判断
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
until hi(tteax) and $01 <>0
//Tteax的高位与$01进行AND运算,如果等于0就跳回去
//第二阶段目的就是赋值给Ttesi
//--------------------------------- //第三阶段
if (ttesi-2<>0) then //当Ttesi-2不等于0时
begin
ttedx:=0;
ttesi:=ttesi+$0FFFFFD;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
ttedx:=buf1
//读取文件给Ttedx赋值
ttebp:=ttedx;
ttesi:= ttesi shl 8;
ttebp:=ttebp+ttesi
//最终目的是为Ttebp赋值
Ti:=Ti+1;
if (ttebp +1=0) then Exit
//这里是出口,Ttebp+1=0时就代表解压文件全部完毕
ttebp:=ttebp+1;
ttesp14:=ttebp
//这里就是把Ttebp转到Ttesp14,也就是后面的新地址指针
end else Ttebp:=Ttesp14
//上面的判断条件不符合的话那么只能用原来的值,(
//--------------------------------- //第四阶段
if (lo(tteax) and $7F =0) then //Tteax判断
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
ttedx:=tteax
//给Ttedx赋值
ttedx:=ttedx shr 8;
ttedx:=ttedx and 1
//Ttedx进行运算
if (lo(tteax) and $7F =0) then //Tteax判断
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
ttesi:=tteax
//给Ttesi赋值
ttesi:=ttesi shr 8;
ttesi:=ttesi and 1;
ttedi:=ttedx*2+ttesi
//Ttedi等于Ttedx的2陪加Ttesi
if (ttedi and ttedi <>0) then //如果Ttedi对自己进行AND运算不等于0的话就开始解压文件
begin
ttedi:=ttedi+2
//Ttedi+2 这时Ttedi就扮演压缩部分大小的值,也就是循环次数
Tdi:=Di-Ttesp14
//新的指针,他的值是目的文件指针-Ttesp14 Ttesp14是第3阶段取得的
DMem.position:=Tdi;
DMem.Read(buf1,1);
Tdi:=Tdi+1;
DMem.position:=Di;
DMem.Write(buf1,1);
Di:=Di+1
//这就是进行第一次解压文件,解开了1个字节
repeat //下面就要开始根据Ttedi的值进行循环解了
DMem.position:=Tdi;
DMem.Read(buf1,1);
DMem.position:=Di;
DMem.Write(buf1,1);
Tdi:=Tdi+1;
Di:=Di+1;
Ttedi:=Ttedi-1
//循环过程,当Ttedi=0时,解文件就完毕了,跳回第一阶段
until Ttedi =0;
end
//---------------------------------
else //如果Ttedi的运算结果=0了,进行下面的候补工作
begin
ttedi:=$01
//给Ttedi新值
repeat //开始循环
if (lo(tteax) and $7F =0) then //判断Tteax
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
ttedx:=tteax
//把Tteax的值给Ttedx
ttedx:=ttedx shr 8;
ttedx:=ttedx and 1;
ttedi:=ttedi*2+ttedx
//Ttedi获得了新的值
if (lo(tteax) and $7F =0) then
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
until hi(tteax) and $01 =0
//Tteax的高位于$01进行AND运算,结果=0的话就跳回去
//----------------------------------
ttedi:=ttedi+2
//不等于0就下来,开始进行解压缩
Tdi:=Di-Ttesp14
//这里和上面是一模一样的,因为我不知道怎么排好循序就写了2个解压缩的位置
DMem.position:=Tdi;
DMem.Read(buf1,1);
Tdi:=Tdi+1;
DMem.position:=Di;
DMem.Write(buf1,1);
Di:=Di+1;
repeat
DMem.position:=Tdi;
DMem.Read(buf1,1);
DMem.position:=Di;
DMem.Write(buf1,1);
Tdi:=Tdi+1;
Di:=Di+1;
Ttedi:=Ttedi-1;
until Ttedi =0
//解完了就回第一阶段
end;
//保存文件
DMem.savetofile(DestFileName);
DMem.Free;//释放
TempMem.Free;//释放
end;
 
在硬盘有AAA。PAK这样一个文件,有如下一个函数,如何调用?
procedure UnPak(PakOffSet,ESize,DSize:integer;SMem:TMemoryStream;DestFileName:String);
var
DMem,TempMem:TMemoryStream;
i:integer;
Buf1:Byte;
Ti,Tdi,Di,Tteax,Ttesi,Ttedx,Ttebp,Ttedi,Ttesp14:integer;
begin
DMem:=TMemoryStream.Create;//目标文件流
TempMem:=TMemoryStream.Create;//临时流
TempMem.SetSize(ESize);//指定临时流大小为压缩大小
DMem.SetSize(DSize);//指定目标流大小为解压缩大小
SMem.position:=PakOffSet;//指定偏移;
TempMem.CopyFrom(SMem,Esize);//从PAK文件流指定偏移读取压缩大小内存块到临时流
//在这里进行处理,把TempMem的内存流处理后写入DMem
Tteax:=0;
Ttesp14:=1;
Ti:=0;
Di:=0;
//--------------------------------- 第一阶段
repeat
if (lo(Tteax) and $7F =0) then //取Tteax的低位与 $7F进行 and运算
begin //如果=0的话就取压缩文件的第一字节FF进行赋予Tteax
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
Tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax
//如果不=0的话tteax就象加也就是说*2
TempMem.position:=Ti
//这里是正常的读取文件,边读边写
TempMem.Read(buf1,1);
DMem.position:=Di;
DMem.write(buf1,1);
Ti:=Ti+1;
Di:=Di+1;
until hi(tteax) and $01 =0
//比较Tteax的高位与 $01 进行 AND运算结果=的话就进入第二阶段
//---------------------------------
Ttesi:=$01
//第二阶段,先给Ttesi赋予1
repeat
if (lo(tteax) and $7F =0) then //对Tteax与 $7F 进行AND运算,结果为0时就读取文件赋予Tteax
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax
//运算结果不为0话就相加
ttedx:=tteax
//Tteax的值传给Ttedx
ttedx:=ttedx shr 8
//Ttedx经过右移运算,AND运算
ttedx:=ttedx and 1;
ttesi:=ttesi*2+ttedx
//Ttesi的值等于Ttesi*2+上面Ttedx运算完毕的值
if (lo(tteax) and $7F =0) then //Tteax判断
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
until hi(tteax) and $01 <>0
//Tteax的高位与$01进行AND运算,如果等于0就跳回去
//第二阶段目的就是赋值给Ttesi
//--------------------------------- //第三阶段
if (ttesi-2<>0) then //当Ttesi-2不等于0时
begin
ttedx:=0;
ttesi:=ttesi+$0FFFFFD;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
ttedx:=buf1
//读取文件给Ttedx赋值
ttebp:=ttedx;
ttesi:= ttesi shl 8;
ttebp:=ttebp+ttesi
//最终目的是为Ttebp赋值
Ti:=Ti+1;
if (ttebp +1=0) then Exit
//这里是出口,Ttebp+1=0时就代表解压文件全部完毕
ttebp:=ttebp+1;
ttesp14:=ttebp
//这里就是把Ttebp转到Ttesp14,也就是后面的新地址指针
end else Ttebp:=Ttesp14
//上面的判断条件不符合的话那么只能用原来的值,(
//--------------------------------- //第四阶段
if (lo(tteax) and $7F =0) then //Tteax判断
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
ttedx:=tteax
//给Ttedx赋值
ttedx:=ttedx shr 8;
ttedx:=ttedx and 1
//Ttedx进行运算
if (lo(tteax) and $7F =0) then //Tteax判断
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
ttesi:=tteax
//给Ttesi赋值
ttesi:=ttesi shr 8;
ttesi:=ttesi and 1;
ttedi:=ttedx*2+ttesi
//Ttedi等于Ttedx的2陪加Ttesi
if (ttedi and ttedi <>0) then //如果Ttedi对自己进行AND运算不等于0的话就开始解压文件
begin
ttedi:=ttedi+2
//Ttedi+2 这时Ttedi就扮演压缩部分大小的值,也就是循环次数
Tdi:=Di-Ttesp14
//新的指针,他的值是目的文件指针-Ttesp14 Ttesp14是第3阶段取得的
DMem.position:=Tdi;
DMem.Read(buf1,1);
Tdi:=Tdi+1;
DMem.position:=Di;
DMem.Write(buf1,1);
Di:=Di+1
//这就是进行第一次解压文件,解开了1个字节
repeat //下面就要开始根据Ttedi的值进行循环解了
DMem.position:=Tdi;
DMem.Read(buf1,1);
DMem.position:=Di;
DMem.Write(buf1,1);
Tdi:=Tdi+1;
Di:=Di+1;
Ttedi:=Ttedi-1
//循环过程,当Ttedi=0时,解文件就完毕了,跳回第一阶段
until Ttedi =0;
end
//---------------------------------
else //如果Ttedi的运算结果=0了,进行下面的候补工作
begin
ttedi:=$01
//给Ttedi新值
repeat //开始循环
if (lo(tteax) and $7F =0) then //判断Tteax
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
ttedx:=tteax
//把Tteax的值给Ttedx
ttedx:=ttedx shr 8;
ttedx:=ttedx and 1;
ttedi:=ttedi*2+ttedx
//Ttedi获得了新的值
if (lo(tteax) and $7F =0) then
begin
tteax:=0;
TempMem.position:=Ti;
TempMem.Read(buf1,1);
tteax:=buf1*2+1;
Ti:=Ti+1;
end else tteax:=tteax+tteax;
until hi(tteax) and $01 =0
//Tteax的高位于$01进行AND运算,结果=0的话就跳回去
//----------------------------------
ttedi:=ttedi+2
//不等于0就下来,开始进行解压缩
Tdi:=Di-Ttesp14
//这里和上面是一模一样的,因为我不知道怎么排好循序就写了2个解压缩的位置
DMem.position:=Tdi;
DMem.Read(buf1,1);
Tdi:=Tdi+1;
DMem.position:=Di;
DMem.Write(buf1,1);
Di:=Di+1;
repeat
DMem.position:=Tdi;
DMem.Read(buf1,1);
DMem.position:=Di;
DMem.Write(buf1,1);
Tdi:=Tdi+1;
Di:=Di+1;
Ttedi:=Ttedi-1;
until Ttedi =0
//解完了就回第一阶段
end;
//保存文件
DMem.savetofile(DestFileName);
DMem.Free;//释放
TempMem.Free;//释放
end;
 
將函數拷貝到自己的Unit裏不就可以了
 
调用一个陌生的函数,读懂原码后,函数需要什么参数就提供什么参数即可
uses 这个procedure所在的单元
定义一个TMemoryStream变量,并create,然后调用该变量的loadfromfile方法(记不清,大概是这个吧)将.pak文件读入到流中,把这个流变量作为procedure的SMem参数传入

再传入
PakOffSet 要从文件流中读入的数据起始位置
ESize 压缩大小
DSize 解压缩大小


 
自己建立一个单元,把这个函数放进来调用就OK了,只是看懂它要干什么真麻烦
 
具体如何调用,请教
 
COPY这段函数到你的单元中
然后调用:
var
i,j,k:integer;
ms:TMemoryStream;
fn:string;
begin
ms:=TMemoryStream.create(self);
UnPak(i,j,k,ms,fn);
......
end;
ok?
 
引用这个单元或者
COPY这段函数到你的单元中//看情况

var
PakOffSet: integer;//指定偏移
ESize: integer;//压缩大小
DSize:integer;//解压缩大小
SMem: TMemoryStream;//原内存流
DestFileName: String;//要保存的目标文件名
begin
SMem := TMemoryStream.create;//创建原内存流
 SMem.LoadFromFile(XXX.PAK);//将XXX.PAK读入SMem流中
PakOffSet := ...//为偏移大小赋值
ESize := ...;//为压缩大小赋值
DSize := ...;//为解压缩大小赋值
 DestFileName := ...;//为目标文件名赋值

UnPak(PakOffSet, ESize, DSize,SMem, DestFileName);//调用此函数解压
......
 SMem.Free;
end;
 
啊,其实hurryfq说的已经很清楚了!
//呵呵,不好意思,多此一举了!
 
问题是
PakOffSet 要从文件流中读入的数据起始位置
ESize 压缩大小
DSize 解压缩大小

这三个变量如何确定呢,总不能想写多少就是多少把
 
后退
顶部