unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TFlatSpeedButtonUnit, ExtCtrls, ComCtrls, ImgList,
MPlayer,shellapi,zlib, Buttons, Menus, TFlatComboBoxUnit, CheckLst,jpeg;
type
Tsourcefm = class(TForm)
Panel1: TPanel;
Image2: TImage;
Panel2: TPanel;
Panel3: TPanel;
Splitter1: TSplitter;
Memo1: TMemo;
Panel4: TPanel;
ListView1: TListView;
Splitter2: TSplitter;
ImageList1: TImageList;
ImageList2: TImageList;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
SpeedButton3: TSpeedButton;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
AG1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
AG2: TMenuItem;
SpeedButton1: TSpeedButton;
FlatComboBox1: TFlatComboBox;
FlatComboBox2: TFlatComboBox;
Panel5: TPanel;
ListBox1: TListBox;
CheckListBox1: TCheckListBox;
SpeedButton2: TSpeedButton;
procedure init;
procedure getinfo;
function getswfinfo:boolean;
procedure gettagid;
procedure addtolistview;
procedure getsound(x:integer);
procedure ListView1DblClick(Sender: TObject);
procedure getimage(x:integer);
procedure ListBox1DblClick(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure AG1Click(Sender: TObject);
procedure AG2Click(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure replacetag(x:integer;filename:string);
procedure getsoundfile(x:integer);
procedure getnoalphajpg(x:integer);
procedure getalphajpg(x:integer);
procedure getjpgfile(x:integer);
procedure getalphabmp(x:integer);
procedure getnoalphabmp(x:integer);
procedure getstreamsoundfile(x:integer;flag:boolean);
procedure SpeedButton1Click(Sender: TObject);
procedure FlatComboBox1Change(Sender: TObject);
procedure replace14(x:integer);
procedure gettag(x:integer);
procedure SpeedButton2Click(Sender: TObject);
procedure PopupMenu1Popup(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
swffilename:string;
savepath:string;
needinit:boolean;
filebuf,buf:array of byte;
end;
type idrec=record
id:byte;
pos,idpos:integer;
length:integer;
end;
type
//Compiler选项Record Field Alignment必须设置为1,保证Record长度正确
//BMP文件头
BitmapFileHeadType = Record
B,M : Char;
bfSize : LongWord;
bfReserved1 : Word;
bfReserved2 : Word;
bfOffBits : LongWord;
end;
//BMP文件图像信息头
BitmapInfoHeadType = Record
biSize : LongWord;
biWidth : LongWord;
biHeight : LongWord;
biPlanes : Word;
biBitCount : Word;
biCompression : LongWord;
biSizeImage : LongWord;
biXPelsPerMeter : LongWord;
biYPelsPerMeter : LongWord;
biClrUsed : LongWord;
biClrImportant : LongWord;
end;
var
sourcefm: Tsourcefm;
currentpos:integer;
filelength:longword;//swf文件大小
ch:array [0..255] of integer;
idbuf: array [0..102400] of idrec;
maxidbuf:integer;
t:tlistitem;
BitmapBuf1,BitmapBuf2 : Array of Byte;
JPEGEncoding,JPEGImage : Array of Byte;
id6tagid:integer;//保存ID=6的TAGID
tmplen:longword;
path:string;//保存上一次释放的资源路径;
showpicfm:boolean;
implementation
uses hexut, picut;
{$R *.dfm}
procedure readtobuf(filename:string);
var f:tmemorystream;
x:integer;
begin
filemode:=fmopenread;
f:=tmemorystream.Create;
f.LoadFromFile(filename);
setlength(sourcefm.filebuf,f.size);
f.Read(sourcefm.filebuf[0],f.size);
tmplen:=f.Size;
f.Free;
end;
procedure Tsourcefm.init;
begin
showpicfm:=true;
needinit:=false;
if swffilename='' then
exit;
readtobuf(swffilename);//读取文件数据
getinfo;
addtolistview;
end;
function Tsourcefm.getswfinfo:boolean;
var swf:string[3];
ver:byte;
b,b1,b2:byte;
framecount:word;
SourceStream: TDecompressionStream;
Buffer: PChar;
Count: Integer;
MS: TMemoryStream;
s:string;
begin
result:=false;
currentpos:=0;
setlength(swf,3);
move(filebuf[currentpos],swf[1],3);
memo1.Lines.Add('标志:'+swf);
inc(currentpos,3);
if (swf<>'FWS') and (swf<>'CWS') then
exit;
move(filebuf[currentpos],ver,1);
inc(currentpos);
if swf='CWS' then
//解压缩FLASH 6版本数据
begin
MS:= TMemoryStream.Create;
ms.Size:=length(filebuf)-currentpos;
move(filebuf[currentpos],ms.memory^,ms.Size);
setlength(filebuf,count+4);
Ms.ReadBuffer(Count, SizeOf(Count));
SourceStream := TDecompressionStream.Create(Ms);
Try
sourcestream.Position:=0;
SourceStream.ReadBuffer(filebuf[currentpos], Count);
ms.Free;
finally
sourcestream.Free;
end;
end;
memo1.Lines.Add('版本:'+inttostr(ver));
if ver<5 then
exit;
move(filebuf[currentpos],filelength,sizeof(filelength));
memo1.Lines.Add('文件长度:'+inttostr(filelength));
inc(currentpos,sizeof(filelength));
Move(FileBuf[CurrentPos],b,1);
Inc(CurrentPos,1);
b2:=b shr 3;
//得到Bit位数
memo1.Lines.Add('bit位:'+inttostr(b));
b2:=5+b2*4;
while (b2 mod 8)<>0do
Inc(b2);
//计算共有多少Bit位数
memo1.Lines.Add('bit数:'+inttostr(b2));
b2:=(b2 div 8)-1;
//计算共有多少字节Byte
memo1.Lines.Add('字节数:'+inttostr(b2));
SetLength(Buf,b2+1);
Buf[0]:=b;
Move(FileBuf[CurrentPos],Buf[1],b2);
Inc(CurrentPos,b2);
//读取FrameRate,b2为小数点前部分,b1为小数点后部分
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Inc(CurrentPos,Sizeof(b1));
Move(FileBuf[CurrentPos],b2,Sizeof(b2));
Inc(CurrentPos,Sizeof(b2));
memo1.Lines.Add('帧速度:'+IntToStr(b2)+'.'+IntToStr(b1));
//读取总帧数FrameCount
Move(FileBuf[CurrentPos],FrameCount,Sizeof(FrameCount));
Inc(CurrentPos,Sizeof(FrameCount));
memo1.lines.add('总帧数'+inttostr(framecount));
result:=true;
end;
procedure Tsourcefm.getinfo;
begin
setlength(JPEGEncoding,0);
setlength(JPEGImage,0);
listbox1.Items.clear;
memo1.Lines.Clear;
if not getswfinfo then
begin
showmessage('不是所要求的文件类型');
exit;
end;
gettagid;
end;
procedure Tsourcefm.gettagid;
var x:integer;
tagid:word;
taglength:longword;
s:string;
f:boolean;
begin
for x:=0 to 255do
ch[x]:=0;
x:=0;
setlength(buf,0);
maxidbuf:=0;
repeat
f:=false;
//读取TagID并得到TagLength
idbuf[maxidbuf].idpos:=CurrentPos;//保存TAGID的位置与POS不同
Move(FileBuf[CurrentPos],TagID,Sizeof(TagID));
Inc(CurrentPos,Sizeof(TagID));
TagLength:=TagID and $3F;
TagID:=TagID shr 6;
if TagLength=$3F then
begin
Move(FileBuf[CurrentPos],TagLength,Sizeof(TagLength));
Inc(CurrentPos,Sizeof(TagLength));
f:=true;
end;
case tagid of
6,8,14,18,19,20,21,35,36,45:begin
end;
else
if f then
listbox1.Items.Add(inttostr(maxidbuf)+':'+'ID:'+inttostr(tagid)+':'+'-pos:'+inttostr(CurrentPos)+'-len:'+inttostr(TagLength)+'...')
else
listbox1.Items.Add(inttostr(maxidbuf)+':'+'ID:'+inttostr(tagid)+':'+'-pos:'+inttostr(CurrentPos)+'-len:'+inttostr(TagLength))
end;
idbuf[maxidbuf].id:=tagid;
idbuf[maxidbuf].length:=taglength;
idbuf[maxidbuf].pos:=CurrentPos;
inc(maxidbuf);
currentpos:=currentpos+taglength;
inc(ch[tagid]);
until tagid=0;
memo1.Lines.Add('共发现ID:'+inttostr(x));
for x:=0 to 255do
begin
s:='ID:'+inttostr(x)+'共有'+inttostr(ch[x]);
if ch[x]<>0 then
case x of
6:memo1.Lines.Add(s+'-JPEG图象扫描行数据');
8:memo1.Lines.Add(s+'-JPEG图象定义');
14:memo1.Lines.Add(s+'-声音');
18:memo1.Lines.Add(s+'-声音(流)');
20:memo1.Lines.Add(s+'-无Alpha的Bitmap数据');
19:memo1.Lines.Add(s+'-声音(流)数据');
21:memo1.Lines.Add(s+'-无Alpha的JPEG数据');
35:memo1.Lines.Add(s+'-有Alpha的JPEG数据');
36:memo1.Lines.Add(s+'-有Alpha的Bitmap数据');
45:memo1.Lines.Add(s+'-声音(流)');
else
memo1.Lines.Add('ID:'+inttostr(x)+'共有'+inttostr(ch[x]));
end;
end;
end;
procedure tsourcefm.getsoundfile(x:integer);
var s:string;
f:tmemorystream;
soundid:word;
SoundInfo:byte;
SoundSampleCount:longword;
begin
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],SoundID,Sizeof(SoundID));
Inc(CurrentPos,Sizeof(SoundID));
Move(FileBuf[CurrentPos],SoundInfo,Sizeof(SoundInfo));
Inc(CurrentPos,Sizeof(SoundInfo));
Move(FileBuf[CurrentPos],SoundSampleCount,Sizeof(SoundSampleCount));
Inc(CurrentPos,Sizeof(SoundSampleCount));
s:='';
case SoundInfo shr 4 of
0,1 : s:='.WAV';
2 : s:='.MP3';
end;
f:=tmemorystream.Create;
f.Size:=idbuf[x].length-sizeof(SoundID);
f.Position:=0;
move(filebuf[idbuf[x].pos+sizeof(SoundID)],f.memory^,f.size);
path:=savepath+inttostr(idbuf[x].id)+'_'+inttostr(x)+s;
f.SaveToFile(path);
f.Free;
ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);
end;
procedure tsourcefm.getnoalphajpg(x:integer);
var BitmapID : Word;
l : LongWord;
b,b1,b2:byte;
f:tmemorystream;
begin
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
b:=0;
l:=0;
//那么只好先过滤掉前面无用的FFD9 FFD8
Repeat
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Move(FileBuf[CurrentPos+1],b2,Sizeof(b2));
if (b1=$FF) and (b2=$D8) then
Inc(b);
Inc(CurrentPos,Sizeof(b1));
Inc(l,Sizeof(b1));
Until b>1;
Dec(CurrentPos,Sizeof(b1));
//将多读出的当前$FF回退
Dec(l,Sizeof(b1));
//将后面的BitmapJPEGImage部分直接生成JPG文件
l:=idbuf[x].length-l-Sizeof(BitmapID);
path:=savepath+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.jpg';
f:=tmemorystream.Create;
f.size:=l;
move(FileBuf[CurrentPos],f.memory^,l);
f.SaveToFile(path);
picfm.Image1.Picture.LoadFromFile(path);
f.Free;
picfm.Panel3.Visible:=false;
picfm.Label1.Caption:=sourcefm.listview1.selected.caption;
if showpicfm then
picfm.Show;
{ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);}
end;
procedure tsourcefm.getalphajpg(x:integer);
var BitmapID : Word;
l,BitmapOffset : LongWord;
b,b1,b2:byte;
f,t:tmemorystream;
begin
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
l:=idbuf[x].length-Sizeof(BitmapID);
Move(FileBuf[CurrentPos],BitmapOffset,Sizeof(BitmapOffset));
Inc(CurrentPos,Sizeof(BitmapOffset));
b:=0;
l:=0;
SetLength(BitmapBuf1,0);
Repeat
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Move(FileBuf[CurrentPos+1],b2,Sizeof(b2));
if (b1=$FF) and (b2=$D8) then
Inc(b);
SetLength(BitmapBuf1,Length(BitmapBuf1)+1);
//将BitmapJPEGEncoding部分读入BitmapBuf1
Move(FileBuf[CurrentPos],BitmapBuf1[Length(BitmapBuf1)-1],Sizeof(b1));
Inc(CurrentPos,Sizeof(b1));
Inc(l,Sizeof(b1));
Until b>1;
//此时BitmapBuf1中应该是BitmapEncoding的内容+$FF
//即 $FFD8 ...... $FFD9 FF,这5个控制字段是要去掉的
//BitmapEncoding中的内容是JPEG的DQT = Define Quantization Table = FFDB
//等内容
Dec(CurrentPos,Sizeof(b1));
//将多读出的当前$FF回退
Dec(l,Sizeof(b1));
b:=0;
SetLength(BitmapBuf2,0);
Repeat
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Move(FileBuf[CurrentPos+1],b2,Sizeof(b2));
if (b1=$FF) and (b2=$DA) then
Inc(b);
SetLength(BitmapBuf2,Length(BitmapBuf2)+1);
//将BitmapJPEGInmage的SOS前面部分读入BitmapBuf2
//FFDA SOS = Start Of Scan是JPEG的图像开始部分,但是它在文件中必须位于
//DQT(FFDB)等内容的后面,所以此处读到这里就停止,以便插入BitmapBuf1
Move(FileBuf[CurrentPos],BitmapBuf2[Length(BitmapBuf2)-1],Sizeof(b1));
Inc(CurrentPos,Sizeof(b1));
Inc(l,Sizeof(b1));
Until b>0;
Dec(CurrentPos,Sizeof(b1));
//将多读出的当前$FF回退
Dec(l,Sizeof(b1));
//由于后面的BitmapAlphaData内容对于JPEG文件没有意义,所以也就不读取了
f:=tmemorystream.Create;
t:=tmemorystream.Create;
f.Position:=0;
f.Write(BitmapBuf2[0],Length(BitmapBuf2)-1);
t.Write(BitmapBuf2[0],Length(BitmapBuf2)-1);
t.SaveToFile(savepath+'2.dat');
T.Size:=0;
f.Position:=f.Size;
f.Write(BitmapBuf1[2],Length(BitmapBuf1)-5);
t.Write(BitmapBuf1[2],Length(BitmapBuf1)-5);
t.SaveToFile(savepath+'1.dat');
t.free;
f.Position:=f.Size;
l:=BitmapOffset-l;
SetLength(BitmapBuf2,l);
//再将BitmapJPEGImage余下的部分读取写入
Move(FileBuf[CurrentPos],BitmapBuf2[0],l);
f.Write(BitmapBuf2[0],Length(BitmapBuf2));
path:=savepath+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.jpg';
f.SaveToFile(path);
picfm.Image1.Picture.LoadFromFile(path);
f.Free;
picfm.Panel3.Visible:=false;
picfm.Label1.Caption:=sourcefm.listview1.selected.caption;
if showpicfm then
picfm.Show;
{ ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);}
end;
procedure tsourcefm.getjpgfile(x:integer);
var BitmapID : Word;
l,BitmapOffset,tmppos : LongWord;
f:tmemorystream;
tmp:byte;
begin
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
l:=idbuf[x].length-Sizeof(BitmapID);
SetLength(JPEGImage,l);
Move(FileBuf[CurrentPos],JPEGImage[0],l);
//由于不确定Tag6和Tag8哪个会在文件中先出现,所以检查JPEGEncoding是否为空
if Length(JPEGEncoding)<>0 then
begin
tmpPos:=0;
//也要先查找SOS的位置,以便插入DQT等BitmapJPEGEncoding内容
Repeat Inc(tmpPos);
Until (JPEGImage[tmpPos]=$FF) and (JPEGImage[tmpPos+1]=$DA);
path:=savepath+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.jpg';
f:=tmemorystream.Create;
f.Write(JPEGImage[0],tmpPos);
f.position:=f.Size;
tmp:=$ff;
f.Write(tmp,1);
tmp:=$db;
f.Write(tmp,1);
f.Write(JPEGEncoding[0],Length(JPEGEncoding)-2);
f.Position:=f.Size;
f.Write(JPEGImage[tmpPos],Length(JPEGImage)-tmpPos);
f.SaveToFile(path);
picfm.Image1.Picture.LoadFromFile(path);
f.Free;
picfm.Panel3.Visible:=false;
picfm.Label1.Caption:=sourcefm.listview1.selected.caption;
if showpicfm then
picfm.Show;
{ ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);}
end
else
showmessage('没有发现JPEG头信息');
end;
procedure tsourcefm.getalphabmp(x:integer);
var BitmapID : Word;
l: LongWord;
f:tmemorystream;
bitmapwidth,BitmapHeight:word;
BitmapFormat:byte;
BitmapColorTableSize1:byte;
BitmapColorTableSize2:word;
BitmapColorTableSize3,BitmapColorTableSize:longword;
inStream:tmemorystream;
zStream:tdecompressionstream;
BitmapFileHead:bitmapfileheadtype;
BitmapInfoHead:bitmapinfoheadtype;
begin
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
Move(FileBuf[CurrentPos],BitmapFormat,Sizeof(BitmapFormat));
Inc(CurrentPos,Sizeof(BitmapFormat));
Move(FileBuf[CurrentPos],BitmapWidth,Sizeof(BitmapWidth));
Inc(CurrentPos,Sizeof(BitmapWidth));
Move(FileBuf[CurrentPos],BitmapHeight,Sizeof(BitmapHeight));
Inc(CurrentPos,Sizeof(BitmapHeight));
l:=idbuf[x].length-Sizeof(BitmapID)-Sizeof(BitmapFormat)-Sizeof(BitmapWidth)-Sizeof(BitmapHeight);
case BitmapFormat of
3 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize1,Sizeof(BitmapColorTableSize1));
Inc(CurrentPos,Sizeof(BitmapColorTableSize1));
l:=l-Sizeof(BitmapColorTableSize1);
BitmapColorTableSize:=BitmapColorTableSize1;
end;
4 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize2,Sizeof(BitmapColorTableSize2));
Inc(CurrentPos,Sizeof(BitmapColorTableSize2));
l:=l-Sizeof(BitmapColorTableSize2);
BitmapColorTableSize:=BitmapColorTableSize2;
end;
5 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize3,Sizeof(BitmapColorTableSize3));
Inc(CurrentPos,Sizeof(BitmapColorTableSize3));
l:=l-Sizeof(BitmapColorTableSize3);
BitmapColorTableSize:=BitmapColorTableSize3;
end;
end;
//先将压缩的ZLIB数据读入BitmapBuf1
SetLength(BitmapBuf1,l);
Move(FileBuf[CurrentPos],BitmapBuf1[0],l);
inStream:=TMemoryStream.Create;
inStream.Write(BitmapBuf1[0],l);
inStream.Position:=0;
zStream:=TDecompressionStream.Create(inStream);
//Color Table也是以32数据为单位的,分别是 R G B (A)
//所以计算长度时要*4
//Image Data也是以32数据为单位的
case BitmapFormat of
3 : begin
l:=BitmapWidth;
while (l mod 4)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*4)+(l*BitmapHeight);
end;
4 : begin
l:=BitmapWidth;
while (l mod 2)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*4)+(l*BitmapHeight*2);
end;
5 : l:=((BitmapColorTableSize+1)*4)+(BitmapWidth*BitmapHeight*4);
end;
//解压缩后的数据存入BitmapBuf2
SetLength(BitmapBuf2,l);
zStream.Read(BitmapBuf2[0],l);
zStream.Free;
inStream.Free;
//Color Table存入BitmapBuf1
SetLength(BitMapBuf1,(BitmapColorTableSize+1)*4);
for l:=0 to BitmapColorTableSizedo
begin
//将Color Table中的RGB(A)值改为BMP文件的BGR(A)顺序
BitmapBuf1[l*4]:=BitmapBuf2[l*4+2];
BitmapBuf1[l*4+1]:=BitmapBuf2[l*4+1];
BitmapBuf1[l*4+2]:=BitmapBuf2[l*4];
BitmapBuf1[l*4+3]:=BitmapBuf2[l*4+3];
end;
//将BitmapBuf2中的Color Table内容去掉,仅保留Image Data
Move(BitmapBuf2[(BitmapColorTableSize+1)*4],BitmapBuf2[0],Length(BitmapBuf2)-((BitmapColorTableSize+1)*4));
SetLength(BitmapBuf2,Length(BitmapBuf2)-((BitmapColorTableSize+1)*4));
//生成BMP文件头BitmapFileHead
FillChar(BitmapFileHead,Sizeof(BitmapFileHead),0);
FillChar(BitmapInfoHead,Sizeof(BitmapInfoHead),0);
//BM标示
BitmapFileHead.B:='B';
BitmapFileHead.M:='M';
//总长度
BitmapFileHead.bfSize:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1)+Length(BitmapBuf2);
//Image Data开始位置
BitmapFileHead.bfOffBits:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1);
//生成BitmapInfoHead
BitmapInfoHead.biSize:=Sizeof(BitmapInfoHead);
BitmapInfoHead.biWidth:=BitmapWidth;
BitmapInfoHead.biHeight:=BitmapHeight;
BitmapInfoHead.biPlanes:=1;
//总为1
case BitmapFormat of
3 : BitmapInfoHead.biBitCount:=8;
4 : BitmapInfoHead.biBitCount:=16;
5 : BitmapInfoHead.biBitCount:=32;
end;
f:=tmemorystream.Create;
f.Write(BitmapFileHead,Sizeof(BitmapFileHead));
f.Position:=f.Size;
f.Write(BitmapInfoHead,Sizeof(BitmapInfoHead));
f.Position:=f.Size;
f.Write(BitmapBuf1[0],Length(BitmapBuf1));
f.Position:=f.Size;
for l:=BitmapHeight-1do
wnto 0do
begin
f.Write(BitmapBuf2[l*(Length(BitmapBuf2) div BitmapHeight)],(Length(BitmapBuf2) div BitmapHeight));
f.Position:=f.Size;
end;
path:=savepath+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.bmp';
f.SaveToFile(path);
picfm.Image1.Picture.LoadFromFile(path);
f.Free;
picfm.Panel3.Visible:=false;
picfm.Label1.Caption:=sourcefm.listview1.selected.caption;
if showpicfm then
picfm.Show;
{ ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);}
end;
procedure tsourcefm.getnoalphabmp(x:integer);
var BitmapID : Word;
l: LongWord;
f:tmemorystream;
bitmapwidth,BitmapHeight:word;
BitmapFormat:byte;
BitmapColorTableSize1:byte;
BitmapColorTableSize2:word;
BitmapColorTableSize3,BitmapColorTableSize:longword;
inStream:tmemorystream;
zStream:tdecompressionstream;
BitmapFileHead:bitmapfileheadtype;
BitmapInfoHead:bitmapinfoheadtype;
begin
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
Move(FileBuf[CurrentPos],BitmapFormat,Sizeof(BitmapFormat));
Inc(CurrentPos,Sizeof(BitmapFormat));
Move(FileBuf[CurrentPos],BitmapWidth,Sizeof(BitmapWidth));
Inc(CurrentPos,Sizeof(BitmapWidth));
Move(FileBuf[CurrentPos],BitmapHeight,Sizeof(BitmapHeight));
Inc(CurrentPos,Sizeof(BitmapHeight));
l:=idbuf[x].length-Sizeof(BitmapID)-Sizeof(BitmapFormat)-Sizeof(BitmapWidth)-Sizeof(BitmapHeight);
case BitmapFormat of
3 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize1,Sizeof(BitmapColorTableSize1));
Inc(CurrentPos,Sizeof(BitmapColorTableSize1));
l:=l-Sizeof(BitmapColorTableSize1);
BitmapColorTableSize:=BitmapColorTableSize1;
end;
4 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize2,Sizeof(BitmapColorTableSize2));
Inc(CurrentPos,Sizeof(BitmapColorTableSize2));
l:=l-Sizeof(BitmapColorTableSize2);
BitmapColorTableSize:=BitmapColorTableSize2;
end;
5 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize3,Sizeof(BitmapColorTableSize3));
Inc(CurrentPos,Sizeof(BitmapColorTableSize3));
l:=l-Sizeof(BitmapColorTableSize3);
BitmapColorTableSize:=BitmapColorTableSize3;
end;
end;
//先将压缩的ZLIB数据读入BitmapBuf1
SetLength(BitmapBuf1,l);
Move(FileBuf[CurrentPos],BitmapBuf1[0],l);
inStream:=TMemoryStream.Create;
inStream.Write(BitmapBuf1[0],l);
inStream.Position:=0;
zStream:=TDecompressionStream.Create(inStream);
//Color Table是以24数据为单位的,分别是 R G B
//所以计算长度时要*3
//Image Data也是以32数据为单位的
case BitmapFormat of
3 : begin
l:=BitmapWidth;
while (l mod 4)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*3)+(l*BitmapHeight);
end;
4 : begin
l:=BitmapWidth;
while (l mod 2)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*3)+(l*BitmapHeight*2);
end;
5 : l:=((BitmapColorTableSize+1)*3)+(BitmapWidth*BitmapHeight*4);
end;
//解压缩后的数据存入BitmapBuf2
SetLength(BitmapBuf2,l);
zStream.Read(BitmapBuf2[0],l);
zStream.Free;
inStream.Free;
//Color Table存入BitmapBuf1
//要将RGB表扩展为BGR(A)表,长度*4
SetLength(BitMapBuf1,(BitmapColorTableSize+1)*4);
for l:=0 to BitmapColorTableSizedo
begin
//将Color Table中的RGB值改为BMP文件的BGR(A)顺序
BitmapBuf1[l*4]:=BitmapBuf2[l*3+2];
BitmapBuf1[l*4+1]:=BitmapBuf2[l*3+1];
BitmapBuf1[l*4+2]:=BitmapBuf2[l*3];
BitmapBuf1[l*4+3]:=0;
end;
//将BitmapBuf2中的Color Table内容去掉,仅保留Image Data
Move(BitmapBuf2[(BitmapColorTableSize+1)*3],BitmapBuf2[0],Length(BitmapBuf2)-((BitmapColorTableSize+1)*3));
SetLength(BitmapBuf2,Length(BitmapBuf2)-((BitmapColorTableSize+1)*3));
//生成BMP文件头BitmapFileHead
FillChar(BitmapFileHead,Sizeof(BitmapFileHead),0);
FillChar(BitmapInfoHead,Sizeof(BitmapInfoHead),0);
//BM标示
BitmapFileHead.B:='B';
BitmapFileHead.M:='M';
//总长度
BitmapFileHead.bfSize:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1)+Length(BitmapBuf2);
//Image Data开始位置
BitmapFileHead.bfOffBits:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1);
//生成BitmapInfoHead
BitmapInfoHead.biSize:=Sizeof(BitmapInfoHead);
BitmapInfoHead.biWidth:=BitmapWidth;
BitmapInfoHead.biHeight:=BitmapHeight;
BitmapInfoHead.biPlanes:=1;
//总为1
case BitmapFormat of
3 : BitmapInfoHead.biBitCount:=8;
4 : BitmapInfoHead.biBitCount:=16;
5 : BitmapInfoHead.biBitCount:=32;
end;
f:=tmemorystream.Create;
f.Write(BitmapFileHead,Sizeof(BitmapFileHead));
f.Position:=f.Size;
f.Write(BitmapInfoHead,Sizeof(BitmapInfoHead));
f.Position:=f.Size;
f.Write(BitmapBuf1[0],Length(BitmapBuf1));
f.Position:=f.Size;
for l:=BitmapHeight-1do
wnto 0do
begin
f.Write(BitmapBuf2[l*(Length(BitmapBuf2) div BitmapHeight)],(Length(BitmapBuf2) div BitmapHeight));
f.Position:=f.Size;
end;
path:=savepath+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.bmp';
f.SaveToFile(path);
picfm.Image1.Picture.LoadFromFile(path);
f.Free;
picfm.Panel3.Visible:=false;
picfm.Label1.Caption:=sourcefm.listview1.selected.caption;
if showpicfm then
picfm.Show;
{ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);}
end;
procedure tsourcefm.getstreamsoundfile(x:integer;flag:boolean);
var f:tmemorystream;
s:string;
StreamHeadb1,StreamHeadb2:byte;
StreamSoundSampleCount:word;
unknow1:word;
len,unknow2:longword;
xname:integer;
count:integer;
begin
currentpos:=idbuf[x].pos;
xname:=x;
count:=0;
setlength(buf,0);
Move(FileBuf[CurrentPos],StreamHeadb1,Sizeof(StreamHeadb1));
Inc(CurrentPos,Sizeof(StreamHeadb1));
Move(FileBuf[CurrentPos],StreamHeadb2,Sizeof(StreamHeadb2));
Inc(CurrentPos,Sizeof(StreamHeadb2));
Move(FileBuf[CurrentPos],StreamSoundSampleCount,Sizeof(StreamSoundSampleCount));
Inc(CurrentPos,Sizeof(StreamSoundSampleCount));
if idbuf[x].id=18 then
//此处有1个UnKnow1数据,占16位,没有用处
Move(FileBuf[CurrentPos],UnKnow1,Sizeof(UnKnow1));Inc(CurrentPos,Sizeof(UnKnow1));
s:='';
case StreamHeadb2 shr 4 of
0,1 : s:='.WAV';
2 : S:='.MP3';
end;
inc(x);
repeat
if idbuf[x].id=19 then
begin
count:=count+1;
currentpos:=idbuf[x].pos;
//去掉一个32位字节的数
Move(FileBuf[CurrentPos],UnKnow2,Sizeof(UnKnow2));Inc(CurrentPos,Sizeof(UnKnow2));
len:=length(buf);
setlength(buf,idbuf[x].length+len-sizeof(unknow2));
Move(FileBuf[CurrentPos],Buf[len],idbuf[x].length-Sizeof(Unknow2));
end;
inc(x);
until (idbuf[x].id=18) or (idbuf[x].id=45) or (idbuf[x].id=0);
if flag then
begin
t.SubItems.Add(inttostr(count));
t.SubItems.add(inttostr(length(buf)));
end
else
begin
if length(buf)>0 then
begin
f:=tmemorystream.Create;
f.Size:=length(buf);
move(buf[0],f.memory^,length(buf));
path:=savepath+inttostr(idbuf[xname].id)+'_'+inttostr(xname)+'流'+s;
f.SaveToFile(path);
f.Free;
ShellExecute(application.handle,nil,pchar(path),nil,nil,SW_SHOWNORMAL);
end
else
showmessage('ID为45的声音数据为空');
if sourcefm.listview1.Selected.SubItems.Count<3 then
sourcefm.listview1.Selected.SubItems.Add(inttostr(count));
if sourcefm.listview1.Selected.SubItems.Count<4 then
sourcefm.listview1.Selected.SubItems.Add(inttostr(length(buf)));
end;
end;
procedure Tsourcefm.getsound(x:integer);
var
soundid:word;
SoundInfo:byte;
SoundSampleCount:longword;
s:string;
StreamHeadb1,StreamHeadb2:byte;
StreamSoundSampleCount:word;
unknow1:word;
begin
currentpos:=idbuf[x].pos;
s:='';
if idbuf[x].id=14 then
begin
Move(FileBuf[CurrentPos],SoundID,Sizeof(SoundID));
Inc(CurrentPos,Sizeof(SoundID));
Move(FileBuf[CurrentPos],SoundInfo,Sizeof(SoundInfo));
Inc(CurrentPos,Sizeof(SoundInfo));
Move(FileBuf[CurrentPos],SoundSampleCount,Sizeof(SoundSampleCount));
Inc(CurrentPos,Sizeof(SoundSampleCount));
case SoundInfo shr 4 of
0,1 : s:='.WAV';
2 : s:='.MP3';
end;
end
else
begin
Move(FileBuf[CurrentPos],StreamHeadb1,Sizeof(StreamHeadb1));
Inc(CurrentPos,Sizeof(StreamHeadb1));
Move(FileBuf[CurrentPos],StreamHeadb2,Sizeof(StreamHeadb2));
Inc(CurrentPos,Sizeof(StreamHeadb2));
Move(FileBuf[CurrentPos],StreamSoundSampleCount,Sizeof(StreamSoundSampleCount));
Inc(CurrentPos,Sizeof(StreamSoundSampleCount));
//此处有1个UnKnow1数据,占16位,没有用处
Move(FileBuf[CurrentPos],UnKnow1,Sizeof(UnKnow1));Inc(CurrentPos,Sizeof(UnKnow1));
case StreamHeadb2 shr 4 of
0,1 : s:='.WAV';
2 : S:='.MP3';
end;
end;
t:=listview1.Items.Add;
if (idbuf[x].id=18) or (idbuf[x].id=45) then
t.Caption:=inttostr(idbuf[x].id)+'_'+inttostr(x)+'流'+s
else
t.Caption:=inttostr(idbuf[x].id)+'_'+inttostr(x)+s;
t.SubItems.Add(inttostr(x));
t.subitems.add(inttostr(idbuf[x].id));
if idbuf[x].id=14 then
begin
t.SubItems.add('1');
t.SubItems.Add(inttostr(idbuf[x].length-2));
end;
t.ImageIndex:=0;
if idbuf[x].id<>14 then
getstreamsoundfile(x,true);
end;
procedure tsourcefm.getimage(x:integer);
var BitmapID : Word;
l,BitmapOffset : LongWord;
b,b1,b2:byte;
tmplen:integer;
flag:boolean;
bitmapwidth,BitmapHeight:word;
BitmapFormat:byte;
BitmapColorTableSize1:byte;
BitmapColorTableSize2:word;
BitmapColorTableSize3,BitmapColorTableSize:longword;
inStream:tmemorystream;
zStream:tdecompressionstream;
BitmapFileHead:bitmapfileheadtype;
BitmapInfoHead:bitmapinfoheadtype;
begin
try
flag:=false;
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
b:=0;
l:=0;
case idbuf[x].id of
21:begin
Repeat
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Move(FileBuf[CurrentPos+1],b2,Sizeof(b2));
if (b1=$FF) and (b2=$D8) then
Inc(b);
Inc(CurrentPos,Sizeof(b1));
Inc(l,Sizeof(b1));
Until b>1;
Dec(CurrentPos,Sizeof(b1));
//将多读出的当前$FF回退
Dec(l,Sizeof(b1));
//将后面的BitmapJPEGImage部分直接生成JPG文件
l:=idbuf[x].length-l-Sizeof(BitmapID);
end;
35:begin
//DefineBitsJPEG3图像
//每段值以JPEG定义的SOI开始,以EOI结束
//SOI = Start Of Image = 'FFD8' 这个标记只在文件开始出现一次
//EOI = End Of Image = 'FFD9' JPG 文件都以 FFD9 结束
Move(FileBuf[CurrentPos],BitmapOffset,Sizeof(BitmapOffset));
Inc(CurrentPos,Sizeof(BitmapOffset));
SetLength(BitmapBuf1,0);
Repeat
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Move(FileBuf[CurrentPos+1],b2,Sizeof(b2));
if (b1=$FF) and (b2=$D8) then
Inc(b);
SetLength(BitmapBuf1,Length(BitmapBuf1)+1);
//将BitmapJPEGEncoding部分读入BitmapBuf1
Move(FileBuf[CurrentPos],BitmapBuf1[Length(BitmapBuf1)-1],Sizeof(b1));
Inc(CurrentPos,Sizeof(b1));
Inc(l,Sizeof(b1));
Until b>1;
//此时BitmapBuf1中应该是BitmapEncoding的内容+$FF
//即 $FFD8 ...... $FFD9 FF,这5个控制字段是要去掉的
//BitmapEncoding中的内容是JPEG的DQT = Define Quantization Table = FFDB
//等内容
Dec(CurrentPos,Sizeof(b1));
//将多读出的当前$FF回退
Dec(l,Sizeof(b1));
b:=0;
SetLength(BitmapBuf2,0);
Repeat
Move(FileBuf[CurrentPos],b1,Sizeof(b1));
Move(FileBuf[CurrentPos+1],b2,Sizeof(b2));
if (b1=$FF) and (b2=$DA) then
Inc(b);
SetLength(BitmapBuf2,Length(BitmapBuf2)+1);
//将BitmapJPEGInmage的SOS前面部分读入BitmapBuf2
//FFDA SOS = Start Of Scan是JPEG的图像开始部分,但是它在文件中必须位于
//DQT(FFDB)等内容的后面,所以此处读到这里就停止,以便插入BitmapBuf1
Move(FileBuf[CurrentPos],BitmapBuf2[Length(BitmapBuf2)-1],Sizeof(b1));
Inc(CurrentPos,Sizeof(b1));
Inc(l,Sizeof(b1));
Until b>0;
Dec(CurrentPos,Sizeof(b1));
//将多读出的当前$FF回退
Dec(l,Sizeof(b1));
//由于后面的BitmapAlphaData内容对于JPEG文件没有意义,所以也就不读取了
tmplen:=Length(BitmapBuf2)-1+Length(BitmapBuf1)-5;
l:=BitmapOffset-l;
inc(tmplen,l);
l:=tmplen;
end;
6:begin
//DefineBits
//与Tag35的BitmapJPEGImage部分内容一致
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
Inc(CurrentPos,Sizeof(BitmapID));
l:=idbuf[x].length-Sizeof(BitmapID);
SetLength(JPEGImage,l);
Move(FileBuf[CurrentPos],JPEGImage[0],l);
//由于不确定Tag6和Tag8哪个会在文件中先出现,所以检查JPEGEncoding是否为空
if Length(JPEGEncoding)<>0 then
begin
tmplen:=0;
//也要先查找SOS的位置,以便插入DQT等BitmapJPEGEncoding内容
Repeat Inc(tmplen);
Until (JPEGImage[tmplen]=$FF) and (JPEGImage[tmplen+1]=$DA);
l:=Length(JPEGEncoding)+Length(JPEGImage);
SetLength(JPEGImage,0);
flag:=true;
id6tagid:=x;
end;
end;
8 : begin
//JPEGTables
//与Tag35的BitmapJPEGEncoding部分内容一致
SetLength(JPEGEncoding,idbuf[x].length-4);
//去掉头尾的 FFD8 FFD9
Move(FileBuf[CurrentPos+2],JPEGEncoding[0],idbuf[x].length-4);
//由于不确定Tag6和Tag8哪个会在文件中先出现,所以检查JPEGImage是否为空
if Length(JPEGImage)<>0 then
begin
tmplen:=0;
//也要先查找SOS的位置,以便插入QDT等BitmapJPEGEncoding内容
Repeat Inc(tmplen);
Until (JPEGImage[tmplen]=$FF) and (JPEGImage[tmplen+1]=$DA);
l:=Length(JPEGEncoding)+Length(JPEGImage);
SetLength(JPEGImage,0);
flag:=true;
end;
end;
36 : begin
Move(FileBuf[CurrentPos],BitmapFormat,Sizeof(BitmapFormat));
Inc(CurrentPos,Sizeof(BitmapFormat));
Move(FileBuf[CurrentPos],BitmapWidth,Sizeof(BitmapWidth));
Inc(CurrentPos,Sizeof(BitmapWidth));
Move(FileBuf[CurrentPos],BitmapHeight,Sizeof(BitmapHeight));
Inc(CurrentPos,Sizeof(BitmapHeight));
l:=idbuf[x].length-Sizeof(BitmapID)-Sizeof(BitmapFormat)-Sizeof(BitmapWidth)-Sizeof(BitmapHeight);
case BitmapFormat of
3 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize1,Sizeof(BitmapColorTableSize1));
Inc(CurrentPos,Sizeof(BitmapColorTableSize1));
l:=l-Sizeof(BitmapColorTableSize1);
BitmapColorTableSize:=BitmapColorTableSize1;
end;
4 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize2,Sizeof(BitmapColorTableSize2));
Inc(CurrentPos,Sizeof(BitmapColorTableSize2));
l:=l-Sizeof(BitmapColorTableSize2);
BitmapColorTableSize:=BitmapColorTableSize2;
end;
5 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize3,Sizeof(BitmapColorTableSize3));
Inc(CurrentPos,Sizeof(BitmapColorTableSize3));
l:=l-Sizeof(BitmapColorTableSize3);
BitmapColorTableSize:=BitmapColorTableSize3;
end;
end;
//先将压缩的ZLIB数据读入BitmapBuf1
SetLength(BitmapBuf1,l);
Move(FileBuf[CurrentPos],BitmapBuf1[0],l);
inStream:=TMemoryStream.Create;
inStream.Write(BitmapBuf1[0],l);
inStream.Position:=0;
zStream:=TDecompressionStream.Create(inStream);
//Color Table也是以32数据为单位的,分别是 R G B (A)
//所以计算长度时要*4
//Image Data也是以32数据为单位的
case BitmapFormat of
3 : begin
l:=BitmapWidth;
while (l mod 4)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*4)+(l*BitmapHeight);
end;
4 : begin
l:=BitmapWidth;
while (l mod 2)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*4)+(l*BitmapHeight*2);
end;
5 : l:=((BitmapColorTableSize+1)*4)+(BitmapWidth*BitmapHeight*4);
end;
//解压缩后的数据存入BitmapBuf2
SetLength(BitmapBuf2,l);
zStream.Read(BitmapBuf2[0],l);
zStream.Free;
inStream.Free;
//Color Table存入BitmapBuf1
SetLength(BitMapBuf1,(BitmapColorTableSize+1)*4);
for l:=0 to BitmapColorTableSizedo
begin
//将Color Table中的RGB(A)值改为BMP文件的BGR(A)顺序
BitmapBuf1[l*4]:=BitmapBuf2[l*4+2];
BitmapBuf1[l*4+1]:=BitmapBuf2[l*4+1];
BitmapBuf1[l*4+2]:=BitmapBuf2[l*4];
BitmapBuf1[l*4+3]:=BitmapBuf2[l*4+3];
end;
//将BitmapBuf2中的Color Table内容去掉,仅保留Image Data
Move(BitmapBuf2[(BitmapColorTableSize+1)*4],BitmapBuf2[0],Length(BitmapBuf2)-((BitmapColorTableSize+1)*4));
SetLength(BitmapBuf2,Length(BitmapBuf2)-((BitmapColorTableSize+1)*4));
//生成BMP文件头BitmapFileHead
FillChar(BitmapFileHead,Sizeof(BitmapFileHead),0);
FillChar(BitmapInfoHead,Sizeof(BitmapInfoHead),0);
//BM标示
BitmapFileHead.B:='B';
BitmapFileHead.M:='M';
//总长度
BitmapFileHead.bfSize:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1)+Length(BitmapBuf2);
//Image Data开始位置
BitmapFileHead.bfOffBits:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1);
//生成BitmapInfoHead
BitmapInfoHead.biSize:=Sizeof(BitmapInfoHead);
BitmapInfoHead.biWidth:=BitmapWidth;
BitmapInfoHead.biHeight:=BitmapHeight;
BitmapInfoHead.biPlanes:=1;
//总为1
case BitmapFormat of
3 : BitmapInfoHead.biBitCount:=8;
4 : BitmapInfoHead.biBitCount:=16;
5 : BitmapInfoHead.biBitCount:=32;
end;
l:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1);
l:=l+length(bitmapbuf2);
end;
20 : begin
Move(FileBuf[CurrentPos],BitmapFormat,Sizeof(BitmapFormat));
Inc(CurrentPos,Sizeof(BitmapFormat));
Move(FileBuf[CurrentPos],BitmapWidth,Sizeof(BitmapWidth));
Inc(CurrentPos,Sizeof(BitmapWidth));
Move(FileBuf[CurrentPos],BitmapHeight,Sizeof(BitmapHeight));
Inc(CurrentPos,Sizeof(BitmapHeight));
l:=idbuf[x].length-Sizeof(BitmapID)-Sizeof(BitmapFormat)-Sizeof(BitmapWidth)-Sizeof(BitmapHeight);
case BitmapFormat of
3 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize1,Sizeof(BitmapColorTableSize1));
Inc(CurrentPos,Sizeof(BitmapColorTableSize1));
l:=l-Sizeof(BitmapColorTableSize1);
BitmapColorTableSize:=BitmapColorTableSize1;
end;
4 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize2,Sizeof(BitmapColorTableSize2));
Inc(CurrentPos,Sizeof(BitmapColorTableSize2));
l:=l-Sizeof(BitmapColorTableSize2);
BitmapColorTableSize:=BitmapColorTableSize2;
end;
5 : begin
Move(FileBuf[CurrentPos],BitmapColorTableSize3,Sizeof(BitmapColorTableSize3));
Inc(CurrentPos,Sizeof(BitmapColorTableSize3));
l:=l-Sizeof(BitmapColorTableSize3);
BitmapColorTableSize:=BitmapColorTableSize3;
end;
end;
//先将压缩的ZLIB数据读入BitmapBuf1
SetLength(BitmapBuf1,l);
Move(FileBuf[CurrentPos],BitmapBuf1[0],l);
inStream:=TMemoryStream.Create;
inStream.Write(BitmapBuf1[0],l);
inStream.Position:=0;
zStream:=TDecompressionStream.Create(inStream);
//Color Table是以24数据为单位的,分别是 R G B
//所以计算长度时要*3
//Image Data也是以32数据为单位的
case BitmapFormat of
3 : begin
l:=BitmapWidth;
while (l mod 4)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*3)+(l*BitmapHeight);
end;
4 : begin
l:=BitmapWidth;
while (l mod 2)<>0do
inc(l);
//长度不足32要补齐
l:=((BitmapColorTableSize+1)*3)+(l*BitmapHeight*2);
end;
5 : l:=((BitmapColorTableSize+1)*3)+(BitmapWidth*BitmapHeight*4);
end;
//解压缩后的数据存入BitmapBuf2
SetLength(BitmapBuf2,l);
zStream.Read(BitmapBuf2[0],l);
zStream.Free;
inStream.Free;
//Color Table存入BitmapBuf1
//要将RGB表扩展为BGR(A)表,长度*4
SetLength(BitMapBuf1,(BitmapColorTableSize+1)*4);
for l:=0 to BitmapColorTableSizedo
begin
//将Color Table中的RGB值改为BMP文件的BGR(A)顺序
BitmapBuf1[l*4]:=BitmapBuf2[l*3+2];
BitmapBuf1[l*4+1]:=BitmapBuf2[l*3+1];
BitmapBuf1[l*4+2]:=BitmapBuf2[l*3];
BitmapBuf1[l*4+3]:=0;
end;
//将BitmapBuf2中的Color Table内容去掉,仅保留Image Data
Move(BitmapBuf2[(BitmapColorTableSize+1)*3],BitmapBuf2[0],Length(BitmapBuf2)-((BitmapColorTableSize+1)*3));
SetLength(BitmapBuf2,Length(BitmapBuf2)-((BitmapColorTableSize+1)*3));
//生成BMP文件头BitmapFileHead
FillChar(BitmapFileHead,Sizeof(BitmapFileHead),0);
FillChar(BitmapInfoHead,Sizeof(BitmapInfoHead),0);
//BM标示
BitmapFileHead.B:='B';
BitmapFileHead.M:='M';
//总长度
BitmapFileHead.bfSize:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1)+Length(BitmapBuf2);
//Image Data开始位置
BitmapFileHead.bfOffBits:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1);
//生成BitmapInfoHead
BitmapInfoHead.biSize:=Sizeof(BitmapInfoHead);
BitmapInfoHead.biWidth:=BitmapWidth;
BitmapInfoHead.biHeight:=BitmapHeight;
BitmapInfoHead.biPlanes:=1;
//总为1
case BitmapFormat of
3 : BitmapInfoHead.biBitCount:=8;
4 : BitmapInfoHead.biBitCount:=16;
5 : BitmapInfoHead.biBitCount:=32;
end;
l:=Sizeof(BitmapFileHead)+Sizeof(BitmapInfoHead)+Length(BitmapBuf1);
l:=l+length(bitmapbuf2);
end;
end;
case idbuf[x].id of
35,21: begin
t:=listview1.Items.Add;
t.Caption:=inttostr(idbuf[x].id)+'_'+inttostr(x)+'.jpg';
t.SubItems.Add(inttostr(x));
t.subitems.add(inttostr(idbuf[x].id));
t.SubItems.Add('1');
t.SubItems.Add(inttostr(l));
t.ImageIndex:=2;
end;
20,36: begin
t:=listview1.Items.Add;
t.Caption:=inttostr(idbuf[x].id)+'_'+inttostr(x)+'.bmp';
t.SubItems.Add(inttostr(x));
t.subitems.add(inttostr(idbuf[x].id));
t.SubItems.Add('1');
t.SubItems.Add(inttostr(l));
t.ImageIndex:=1;
end;
6,8:if flag then
begin
t:=listview1.Items.Add;
t.Caption:=inttostr(idbuf[id6tagid].id)+'_'+inttostr(id6tagid)+'.jpg';
t.SubItems.Add(inttostr(id6tagid));
t.subitems.add(inttostr(idbuf[id6tagid].id));
t.SubItems.Add('1');
t.SubItems.Add(inttostr(l));
t.ImageIndex:=2;
end;
end;
except
t:=listview1.Items.Add;
case idbuf[x].id of
20,36:begin
t.Caption:='无法读取'+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.bmp';
t.ImageIndex:=1;
end;
8,21,35:begin
t.Caption:='无法读取'+inttostr(idbuf[x].id)+'_'+inttostr(x)+'.jpg';
t.ImageIndex:=2;
end;
end;
t.SubItems.Add(inttostr(x));
t.subitems.add(inttostr(idbuf[x].id));
t.SubItems.Add('0');
t.SubItems.Add('0');
end;
end;
procedure Tsourcefm.gettag(x:integer);
var cc:integer;
t:tlistitem;
begin
t:=listview1.Items.Add;
t.Caption:=inttostr(idbuf[x].id)+'_'+inttostr(x)+'.tag';
t.SubItems.Add(inttostr(x));
t.subitems.add(inttostr(idbuf[x].id));
t.SubItems.Add('1');
t.SubItems.Add(inttostr(idbuf[x].length));
t.ImageIndex:=3;
end;
procedure Tsourcefm.addtolistview;
var x,y:integer;
begin
listview1.Items.Clear;
if flatcombobox2.ItemIndex=0 then
begin
for x:=0 to maxidbufdo
case idbuf[x].id of
14,18,45:getsound(x);//声音数据
21,35,6,8,36,20:getimage(x);
//图片数据
else
end;
end
else
for x:=0 to maxidbufdo
if checklistbox1.Checked[idbuf[x].id] then
gettag(x);
end;
procedure Tsourcefm.ListView1DblClick(Sender: TObject);
var x:integer;
begin
picfm.replacetag:=false;
picfm.checkreplace;
if listview1.Selected<>nil then
begin
x:=strtoint(listview1.Selected.SubItems[0]);
if listview1.Selected.SubItems[3]='0' then
showmessage('没有数据,长度为0')
else
case idbuf[x].id of
14:getsoundfile(x);
18,45:getstreamsoundfile(x,false);
21:getnoalphajpg(x);
35:getalphajpg(x);
6:getjpgfile(x);
36:getalphabmp(x);
20:getnoalphabmp(x);
end;
end;
end;
procedure showsource(itemindex:integer);
begin
end;
procedure Tsourcefm.ListBox1DblClick(Sender: TObject);
var s:string;
idx:string;
f:tmemorystream;
len:integer;
tagid:word;
taglength:longword;
begin
if listbox1.ItemIndex>0 then
begin
s:=listbox1.Items[listbox1.ItemIndex];
idx:=copy(s,1,pos('ID',s)-2);
currentpos:=idbuf[strtoint(idx)].idpos;
Move(filebuf[CurrentPos],TagID,Sizeof(TagID));
{inc(currentpos,sizeof(tagid));}
TagLength:=TagID and $3F;
TagID:=TagID shr 6;
if TagLength=$3F then
begin
len:=idbuf[strtoint(idx)].length+4;
end
else
len:=idbuf[strtoint(idx)].length;
len:=len+2;
f:=tmemorystream.Create;
f.Size:=len;
move(filebuf[currentpos],f.memory^,len);
hexfm.Caption:=idx;
hexfm.HexEditor1.LoadFromStream(f);
hexfm.Show;
f.Position:=0;
f.Read(tagid,2);
hexfm.Label1.Caption:=inttostr(tagid);
TagLength:=TagID and $3F;
TagID:=TagID shr 6;
if TagLength=$3F then
begin
f.Read(taglength,4);
end;
hexfm.Label2.Caption:=inttostr(taglength);
hexfm.Label3.Caption:=inttostr(tagid);
f.Free;
end;
end;
procedure savetag(x:integer;filename:string);
var tagid:word;
taglength,startpos,endpos,len:longword;
f:tmemorystream;
begin
filename:=uppercase(filename);
if pos('.TAG',filename)<=0 then
filename:=filename+'.tag';
idbuf[maxidbuf].idpos:=CurrentPos;//保存TAGID的位置与POS不同
startpos:=idbuf[x].idpos;
endpos:=idbuf[x].pos+idbuf[x].length;
f:=tmemorystream.Create;
f.Write(sourcefm.filebuf[startpos],endpos-startpos);
f.SaveTofile(filename);
f.Free;
end;
procedure Tsourcefm.replacetag(x:integer;filename:string);
var f:tmemorystream;
tagid:word;
taglength,startpos,endpos,len:longword;
BitmapID:word;
t,m:array of byte;
begin
f:=tmemorystream.Create;
f.LoadFromFile(FileName);
setlength(m,f.size);
f.Read(m[0],f.size);
f.Position:=0;
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],BitmapID,Sizeof(BitmapID));
currentpos:=0;
Move(m[CurrentPos],TagID,Sizeof(TagID));
Inc(CurrentPos,Sizeof(TagID));
TagLength:=TagID and $3F;
TagID:=TagID shr 6;
if TagLength=$3F then
begin
Move(m[CurrentPos],TagLength,Sizeof(TagLength));
Inc(CurrentPos,Sizeof(TagLength));
end;
m[currentpos]:=bitmapid mod 256;
m[currentpos+1]:=bitmapid div 256;
startpos:=idbuf[x].idpos;
endpos:=idbuf[x].pos+idbuf[x].length;
filelength:=filelength-endpos+startpos;
setlength(t,startpos+f.size+tmplen-endpos);
move(filebuf[0],t[0],startpos);
move(m[0],t[startpos],length(m));
move(filebuf[endpos],t[startpos+f.size],tmplen-endpos);
setlength(filebuf,length(t));
tmplen:=length(filebuf);
move(t[0],filebuf[0],length(t));
len:=length(t);
filebuf[4]:=len mod 256;len:=len div 256;
filebuf[5]:=len mod 256;len:=len div 256;
filebuf[6]:=len mod 256;len:=len div 256;
filebuf[7]:=len ;
f.free;
showpicfm:=true;
needinit:=false;
getinfo;
addtolistview;
speedbutton1.Enabled:=true;//可以保存
SHOWMESSAGE('替换成功');
setlength(t,0);
setlength(m,0);
end;
procedure Tsourcefm.SpeedButton3Click(Sender: TObject);
begin
picfm.FileListBox1.Directory:=picfm.shelltreeview1.Path;
picfm.Panel3.Visible:=true;
picfm.ShowModal;
end;
procedure Tsourcefm.FormCreate(Sender: TObject);
var x:byte;
begin
checklistbox1.Clear;
for x:=0 to 100do
checklistbox1.Items.Add(inttostr(x));
savepath:=extractfiledir(application.ExeName);
if savepath[length(savepath)]<>'/' then
savepath:=savepath+'/';
savepath:=savepath+'temp';
showmessage(savepath);
{ if not fileexists(savepath) then
begin
try
mkdir(savepath);
except
end;
end;
}
savepath:=savepath+'/';
end;
procedure Tsourcefm.FormClose(Sender: TObject;
var Action: TCloseAction);
var f:tsearchrec;
begin
findfirst(savepath+'*.*',faanyfile,f);
deletefile(f.Name);
while findnext(f)=0do
begin
deletefile(savepath+f.Name);
end;
end;
procedure Tsourcefm.AG1Click(Sender: TObject);
var x:integer;
begin
if listview1.Selected=nil then
exit;
x:=strtoint(listview1.Selected.SubItems[0]);
if listview1.Selected.SubItems[3]='0' then
exit;
savedialog1.Filter:='SWFTAG|*.tag';
if not savedialog1.Execute then
exit;
savetag(x,ChangeFileExt(savedialog1.FileName,'.TAG'));
end;
procedure Tsourcefm.AG2Click(Sender: TObject);
var x:integer;
begin
opendialog1.Filter:='SWFTAG|*.tag';
if listview1.Selected<>nil then
begin
x:=strtoint(listview1.Selected.SubItems[0]);
if listview1.Selected.SubItems[3]='0' then
begin
showmessage('没有数据,长度为0');
exit;
end
else
begin
case idbuf[x].id of
2,10,11,13,21,35,20,36,39:if opendialog1.Execute then
replacetag(x,opendialog1.Filename);
end;
end;
end;
end;
procedure Tsourcefm.N1Click(Sender: TObject);
var f:tmemorystream;
begin
savedialog1.Filter:='';
savedialog1.FileName:=listview1.Selected.Caption;
if savedialog1.Execute then
begin
showpicfm:=false;
ListView1DblClick(sender);
showpicfm:=true;
f:=tmemorystream.Create;
f.LoadFromFile(path);
f.SaveTofile(savedialog1.filename);
f.Free;
deletefile(path);
end;
end;
procedure tsourcefm.replace14(x:integer);
var f:tmemorystream;
soundid:word;
SoundInfo:byte;
len,SoundSampleCount:longword;
buf:array of byte;
begin
opendialog1.Filter:='SOUND file|*.mp3';
if not opendialog1.Execute then
exit;
F:=TMEMORYSTREAM.Create;
f.LoadFromFile(opendialog1.FileName);
currentpos:=idbuf[x].pos;
Move(FileBuf[CurrentPos],SoundID,Sizeof(SoundID));
Inc(CurrentPos,Sizeof(SoundID));
Move(FileBuf[CurrentPos],SoundInfo,Sizeof(SoundInfo));
Inc(CurrentPos,Sizeof(SoundInfo));
Move(FileBuf[CurrentPos],SoundSampleCount,Sizeof(SoundSampleCount));
Inc(CurrentPos,Sizeof(SoundSampleCount));
setlength(buf,9);
buf[0]:=$bf;buf[1]:=$03;
buf[6]:=soundid mod 256;
buf[7]:=soundid div 256;
case SoundInfo shr 4 of
0,1 : buf[8]:=0;
2 : BUF[8]:=$2A;
end;
len:=f.size+3;
setlength(buf,9+f.size);
move(f.memory^,buf[9],f.size);
f.clear;
f.Write(buf[0],length(buf));
f.SaveToFile(savepath+'tmp.tag');
f.Free;
sourcefm.replacetag(x,savepath+'tmp.tag');
end;
procedure Tsourcefm.N3Click(Sender: TObject);
begin
ListView1DblClick(sender);
picfm.FormResize(Sender);
if strtoint(listview1.Selected.SubItems[1])=14 then
showmessage('声音资源无法替换!')
{replace14(strtoint(listview1.Selected.SubItems[0]))}
else
begin
if not picfm.Visible then
picfm.show;
picfm.Label2.Caption:='要替换的资源名:'+listview1.selected.Caption+' '+inttostr(picfm.image1.Picture.width)+'X'+inttostr(picfm.Image1.picture.Height);
picfm.tagimagewidth:=picfm.Image1.Picture.Width;
picfm.tagimageheight:=picfm.Image1.Picture.Height;
picfm.tagx:=strtoint(listview1.Selected.SubItems[0]);
picfm.tagimageid:=strtoint(listview1.Selected.SubItems[1]);
picfm.Label3.Caption:=listview1.Selected.SubItems[1];
picfm.Panel3.Visible:=true;
picfm.Image1.Picture:=nil;
picfm.replacetag:=true;
picfm.checkreplace;
end;
end;
procedure Tsourcefm.SpeedButton1Click(Sender: TObject);
var f:tmemorystream;
begin
savedialog1.Filter:='SWF file|*.swf';
if savedialog1.Execute then
begin
f:=tmemorystream.Create;
f.Size:=length(filebuf);
f.Write(filebuf[0],f.size);
F.SaveToFile(SAVEDIALOG1.FileName);
f.Free;
speedbutton1.Enabled:=false;
end;
end;
procedure Tsourcefm.FlatComboBox1Change(Sender: TObject);
begin
case flatcombobox1.ItemIndex of
0:listview1.ViewStyle:=VSICON;
1:listview1.ViewStyle:=VSSMALLICON;
2:listview1.ViewStyle:=VSREPORT;
end;
end;
procedure Tsourcefm.SpeedButton2Click(Sender: TObject);
begin
addtolistview;
end;
procedure Tsourcefm.PopupMenu1Popup(Sender: TObject);
begin
n1.Enabled:=flatcombobox2.ItemIndex=0;
n3.Enabled:=flatcombobox2.ItemIndex=0;
end;
end.