读取SWF头部信息Getting info from SWF-file

      DELPHI 2006-1-9 9:25
A little theory
Any SWF-file consists of 2 main parts: Header and Body. So reading of header is enough to get info about the movie. Header record is described by the following structure:

//头部结构
TSWFHeader = packed record
Signature: array [0..2] of char;
Version: byte;
FileLength: cardinal;
FrameSize: TSWFRect;
FrameRate: byte;
FrameRateRemainder: byte;
FrameCount: cardinal;
end;

TSWFRect = packed record Xmin: integer; // in twips Xmax: integer; // in twips Ymin: integer; // in twips Ymax: integer; // in twipsend;

Header reading is complicated by two features:
1. Size of header record is not a fixed value because of the bit-packing techniques used for Rect record storing. Rect structure: Nbits, Xmin, Xmax, Ymin, Ymax. The unsigned Nbits field occupies the first five bits and indicates how long the next four signed fields are.
2. In compressed format a part of header is stored in the packed part of the file. Has been uncompressed using the open standard ZLIB. The data format used by the ZLIB library is described by Request for Comments (RFCs) documents 1950 to 1952.
//获取信息的函数定义
Function GetSwfFileHeader
function GetSwfFileHeader(const FileName: String; var Header: TSWFHeader): boolean;

Function returns true if the file is read successfully. Rect record fields are in twips (1 px = 20 twips). Frame rate consists of 2 parts: FrameRate is integer and FrameRateRemainder is fractional. The complete value is calculated from
FrameRate + FrameRateRemainder / 256.

How it works:
1. Reading first 8 bytes. This is non compressed part of header.
2. Signature comparing. Unpacking in case compressed format.
3. Reading the Rect bit structure and other data.

Function GetSwfFileHeader(const FileName: string; var Header: TSWFHeader): boolean;
const
BuffSize = 25;
var
Buffer: PByteArray;
NBitsField: byte;
Poz: longword;
FileStream: TFileStream;
MemStream: TMemoryStream;
ZStream: TDecompressionStream;
begin
Result:= FALSE;
if not FileExists(FileName) then Exit;
FileStream:= TFileStream.Create(FileName, fmOpenRead);
try
FileStream.Position:= 0;
if FileStream.Size > 22 then
begin
GetMem(Buffer, BuffSize);
try
FileStream.Read(Header, 8);
if(Header.Signature = 'CWS') and (Header.Version >= 6) then
begin
Result:= TRUE;
MemStream:= TMemoryStream.Create;
try
MemStream.CopyFrom(FileStream, FileStream.Size-8);
MemStream.Position:= 0;
ZStream:= TDecompressionStream.Create(MemStream);
try
ZStream.Read(Buffer^, BuffSize);
finally
ZStream.Free;
end;
finally
MemStream.Free;
end;
end
else begin
FileStream.Read(Buffer^, BuffSize);
Result:= Header.Signature = 'FWS';
end;

if Result then
with Header do
begin
Poz:= 0;
NBitsField:= TBitWidth(ReadNBits(Buffer^, Poz, 5)); Inc(Poz, 5);
FrameSize.Xmin:= Integer(ReadNBits(Buffer^, Poz, NBitsField)); Inc(Poz, NBitsField);
FrameSize.Xmax:= Integer(ReadNBits(Buffer^, Poz, NBitsField)); Inc(Poz, NBitsField);
FrameSize.Ymin:= Integer(ReadNBits(Buffer^, Poz, NBitsField)); Inc(Poz, NBitsField);
FrameSize.Ymax:= Integer(ReadNBits(Buffer^, Poz, NBitsField)); Inc(Poz, NBitsField);
NBitsField:= Poz mod 8;
Poz:= Poz div 8;
if (NBitsField > 0) then Inc(Poz);
FrameRateRemainder:= Buffer^[Poz]; // 8.[8]
FrameRate:= Buffer^[Poz+1];
FrameCount:= Buffer^[Poz+2] or (Buffer^[Poz+3] shl 8);
end;

finally
FreeMem(Buffer);
end;
end;
finally
FileStream.Free;
end;
end;

标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commenttime}{commentauthor}

{CommentUrl}
{commentcontent}