?? unitclassextract.pas
字號:
{*******************************************************}
{ }
{ eulB's 魔法BMP }
{ }
{ 提取文件類 }
{ }
{ 2001年10月20日 }
{ }
{*******************************************************}
unit unitClassExtract;
interface
uses
windows,Gauges,unitClass,SysUtils,Dialogs;
const
NONE_MOD=0;
ONE_MOD=1;
TWO_MOD=2;
type
TExtract=class(Tprocfunc)
private
FBMPName: string;
FGauge: TGauge;
FOpenDialog: TOpenDialog;
procedure FExtract(filename: string;bmpname: string;pb: TGauge);
procedure FExtract_Hi(filename: string;bmpname: string;pb: TGauge);
procedure FBits2Bytes(bits: array of byte;var bytes: array of byte;Flag:integer);
procedure FExtractFromRGB(var p_byte_bufs: array of byte;var f_bit_buf: byte;Flag: integer);
procedure FSetBMPName(value: string);
procedure FSetGauge(value: TGauge);
procedure FSetOpenDialog(value: TOpenDialog);
function FGetPassword(bmpfile: string): string;
function FGetUsePassword: Boolean;
function FGetBMPSize: integer;
public
function Extract: Boolean; //用來表示opendialog執(zhí)行是否成功(即有無按取消鍵)
function Validate :Boolean; //所選文件中有隱藏文件嗎?
function GetPassword: string;
procedure EraseHiddenFile; //銷毀BMP中隱藏的文件
procedure DelBMP; //刪除已隱藏過文件的BMP
constructor create;
published
property BMPName: string write FSetBMPName;
property BMPSize: integer read FGetBMPSize;
property UsePassword: Boolean read FGetUsePassword Default false;
property GaugeInstance: TGauge write FSetGauge;
property OpenDialog: TOpenDialog write FSetOpenDialog;
end;
implementation
constructor TExtract.create;
begin
end;
procedure TExtract.FSetBMPName(value: string);
begin
FBMPName:=value;
end;
procedure TExtract.FSetGauge(value: TGauge);
begin
FGauge:=value;
end;
function TExtract.FGetPassword(bmpfile: string): string;
var
p: hfile;
i: integer;
psw_bit_bufs: array[0..4] of byte;
psw_byte_bufs,p_byte_bufs: array[0..3] of byte;
begin
p:=_lopen(PChar(bmpfile),OF_READ);
_llseek(p,strtoint(GetBMPInfo(bmpfile,BMPDataOffset)),0);
for i:=0 to 3 do
begin
_lread(p,@p_byte_bufs,3);
FExtractFromRGB(p_byte_bufs,psw_bit_bufs[i],NONE_MOD);
end;
FBits2Bytes(psw_bit_bufs,psw_byte_bufs,NONE_MOD);
for i:=0 to 2 do result:=result+chr(psw_byte_bufs[i]);
for i:=0 to 3 do
begin
_lread(p,@p_byte_bufs,3);
FExtractFromRGB(p_byte_bufs,psw_bit_bufs[i],NONE_MOD);
end;
FBits2Bytes(psw_bit_bufs,psw_byte_bufs,NONE_MOD);
for i:= 0 to 2 do result := result + chr(psw_byte_bufs[i]);
result := Trim(result);
end;
function TExtract.GetPassword: string;
begin
result:=FGetPassword(FBMPName);
end;
function TExtract.FGetUsePassword: Boolean;
begin
if GetBMPInfo(FBMPName,BMPFilePswAdded) = 'P' then
result:=true
else
result:=false;
end;
procedure TExtract.FSetOpenDialog(value: TOpenDialog);
begin
FOpenDialog:=value;
end;
function TExtract.FGetBMPSize: integer;
begin
result:=GetFileSize(FBMPName) div 1024;
end;
procedure TExtract.DelBMP;
begin
DeleteFile(FBMPName);
end;
procedure TExtract.FExtract(filename: string;bmpname: string;pb: TGauge);
var
i,file_len,len: Integer;
f,b: hfile;
byte_buf: byte;
byte_bufs: array[0..7] of byte;
begin
pb.MinValue :=0;
b:=_lopen(pchar(bmpname),OF_READWRITE);
f:=_lcreat(pchar(filename),0);
len:=0;
//從圖像頭部偏移2處讀取被隱藏文件長度
_llseek(b,2,0);
_lread(b,@file_len,4);
//定位讀寫指針到圖像的位圖陣列+24處
_llseek(b,strtoint(GetBMPInfo(bmpname,BMPDataOffset))+24,0);
pb.MaxValue :=file_len;
pb.Visible :=true;
//開始讀取
while (len< file_len) do
begin
inc(len);
pb.Progress :=len;
byte_buf:=0;
_lread(b,@byte_bufs,8);
for i:=0 to 7 do
if (byte_bufs[i] and 1 ) = 1 then
byte_buf:= byte_buf or mask[i];
_lwrite(f,@byte_buf,1);
end;
_lclose(f);
_lclose(b);
pb.Visible :=false;
end;
procedure TExtract.FBits2Bytes(bits: array of byte;var bytes: array of byte;Flag:integer);
begin
case Flag of
NONE_MOD:
begin
bytes[0]:=(bits[0] shl 2) or (bits[1] shr 4);
bytes[1]:=(bits[1] shl 4) or (bits[2] shr 2);
bytes[2]:=(bits[2] shl 6) or bits[3];
end;
ONE_MOD:
begin
bytes[0]:=(bits[0] shl 2) or bits[1];
end;
TWO_MOD:
begin
bytes[0]:=(bits[0] shl 2) or (bits[1] shr 4);
bytes[1]:=(bits[1] shl 4) or bits[2];
end;
end;
end;
procedure TExtract.FExtractFromRGB(var p_byte_bufs: array of byte;var f_bit_buf: byte;Flag: integer);
const
R=0;
G=1;
B=2;
begin
case Flag of
NONE_MOD:
begin
//R 取低2位 3--0000 0011
f_bit_buf:=p_byte_bufs[R] and 3;
//G 取低1位
f_bit_buf:=f_bit_buf or ((p_byte_bufs[G] and 1) shl 2);
//B 取低3位 7--0000 0111
f_bit_buf:=f_bit_buf or ((p_byte_bufs[B] and 7) shl 3);
end;
ONE_MOD:
begin
//直接取R的低2位 f_bit_buf:=0000 00xx
f_bit_buf:=p_byte_bufs[R] and 3;
end;
TWO_MOD:
begin
//取R的低2位 f_bit_buf:=0000 xxxx
f_bit_buf:=p_byte_bufs[R] and 3;
//G 取低1位
f_bit_buf:=f_bit_buf or ((p_byte_bufs[G] and 1) shl 2);
//B 取低1位 !!
f_bit_buf:=f_bit_buf or ((p_byte_bufs[B] and 1) shl 3);
end;
end;
end;
procedure TExtract.FExtract_Hi(filename: string;bmpname: string;pb: TGauge);
var
f,p:hfile;
i,iTemp:integer;
file_len,len:integer;
f_byte_bufs:array[0..2] of byte;
f_bit_bufs:array[0..3] of byte;
p_byte_bufs:array[0..2] of byte;
begin
pb.MinValue :=0;
p:=_lopen(pchar(bmpname),OF_READWRITE);
f:=_lcreat(pchar(filename),0);
len:=0;
//從圖像頭部偏移2處讀取被隱藏文件長度
_llseek(p,2,0);
_lread(p,@file_len,4);
iTemp:=file_len;
//定位讀寫指針到圖像的位圖陣列開始處
_llseek(p,strtoint(GetBMPInfo(bmpname,BMPDataOffset))+24,0);
file_len:=file_len div 3;
pb.MaxValue :=file_len;
pb.Visible :=true;
//開始讀取圖像文件p
while (len < file_len) do
begin
inc(len);
pb.Progress:=len;
for i:=0 to 3 do
begin
_lread(p,@p_byte_bufs,3);
FExtractFromRGB(p_byte_bufs,f_bit_bufs[i],NONE_MOD);
end;
FBits2Bytes(f_bit_bufs,f_byte_bufs,NONE_MOD);
_lwrite(f,@f_byte_bufs,3);
end;
case (iTemp mod 3) of
1://file 還剩一個byte-->f_bit_bufs[0]、f_bit_bufs[1](0000 00xx)
begin
_lread(p,@p_byte_bufs,3);
//f_bit_bufs[0]中有file最后一個byte的高6位
FExtractFromRGB(p_byte_bufs,f_bit_bufs[0],NONE_MOD);
_lread(p,@p_byte_bufs,1);
//f_bit_bufs[1]中有file最后一個byte的低2位
FExtractFromRGB(p_byte_bufs,f_bit_bufs[1],ONE_MOD);
//合并成file的最后一個byte
FBits2Bytes(f_bit_bufs,f_byte_bufs,ONE_MOD);
_lwrite(f,@f_byte_bufs,1);
end;
2://file 還剩二個byte-->f_bit_bufs[0]、f_bit_bufs[1]、f_bit_bufs[2](0000 xxxx)
begin
_lread(p,@p_byte_bufs,3);
FExtractFromRGB(p_byte_bufs,f_bit_bufs[0],NONE_MOD);
_lread(p,@p_byte_bufs,3);
FExtractFromRGB(p_byte_bufs,f_bit_bufs[1],NONE_MOD);
_lread(p,@p_byte_bufs,3);
FExtractFromRGB(p_byte_bufs,f_bit_bufs[2],TWO_MOD);
//合并成file的最后二個bytes
FBits2Bytes(f_bit_bufs,f_byte_bufs,TWO_MOD);
_lwrite(f,@f_byte_bufs,2);
end;
end;
_lclose(f);
_lclose(p);
pb.Visible :=false;
end;
function TExtract.Validate :Boolean;
begin
if GetBMPInfo(FBMPName,BMPFilePushed) <> 'J' then
result:=false
else
result:=true;
end;
procedure TExtract.EraseHiddenFile;
var
p: hfile;
byte_buf: byte;
i: shortint;
begin
p:=_lopen(pchar(FBMPName),OF_READWRITE);
//消除7h處的'P'標志位
SetBMPFlag(FBMPName,UN_BMPFilePswAdded);
//消除6h處的'J'標志位
SetBMPFlag(FBMPName,UN_BMPFilePushed);
//銷毀密碼
_llseek(p,strtoint(GetBMPInfo(FBMPName,BMPDataOffset)),0);
for i:=1 to 12 do
begin
_lread(p,@byte_buf,1);
byte_buf:=byte_buf and $FE;
_llseek(p,-1,FILE_CURRENT);
_lwrite(p,@byte_buf,1);
end;
//定位讀寫指針到圖像的位圖陣列開始處
_llseek(p,strtoint(GetBMPInfo(FBMPName,BMPDataOffset))+24,0);
//破壞隱藏文件的前66個字節(jié)
for i:=1 to 66 do
begin
_lread(p,@byte_buf,1);
byte_buf:=byte_buf and $FE;
_llseek(p,-1,FILE_CURRENT);
_lwrite(p,@byte_buf,1);
end;
_lclose(p);
end;
function TExtract.Extract;
var
s:string; //開始時暫時用來存放Filter,然后用來暫時存放Filename,最后用來存放'.tmp'文件路徑
position:shortint;
begin
try
//為了只利用一個變量s,注意以下執(zhí)行的順序!!!
//彈出Savedialog給用戶選擇存放輸出文件的路徑和文件名
s:=ExtractFileExt(GetFileNameFromBMP(FBMPName));
FOpenDialog.DefaultExt:=s;
position:=pos('.',s); //消除'.'
Delete(s,position,1);
s:='All Files (*.*)|*.*|'+s+' Files (*.'+s+')|*.'+Uppercase(s);
FOpenDialog.Filter:=s; //到此變量s使用完畢
FOpenDialog.FilterIndex:=2;
FOpenDialog.FileName:=ExtractFileName(GetFileNameFromBMP(FBMPName));
//產生臨時輸出文件,以'.tmp' 為后綴,這里再次用到變量s
s:=ChangeFileExt(ExtractFilePath(FBMPName)+
GetFileNameFromBMP(FBMPName),'.tmp');
FExtract_Hi(s,FBMPName,FGauge);
FOpenDialog.Title:='保存文件';
if FOpenDialog.Execute then
begin
MoveFile(pchar(s),pchar(FOpenDialog.FileName));
result:=true; //執(zhí)行成功,可憑此在界面中使plExtractPsw不可見
FOpenDialog.Title:='打開';
end else
begin //摁取消鍵后,刪除臨時文件
FOpenDialog.Title:='打開';
DeleteFile(s);
result:=false; //執(zhí)行失敗
end;
except
on E:Exception do
begin
E.Create(E.Message);
result:=false;
end;
end;
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -