Original news here
Many users ask me how to get dimensions of a movie. The answer is simple: just decode an SWF header. All Macromedia Flash (SWF) files begin with the following header (see SWF specification for more information):Field Type Comment
Signature UI8 Signature byte always ‘F’
Signature UI8 Signature byte always ‘W’
Signature UI8 Signature byte always ‘S’
Version UI8 Single byte file version (e.g. 0×04F for SWF 4)
FileLength UI32 Length of entire file in bytes
FrameSize RECT Frame size in twips
FrameRate UI16 Frame delay in 8.8 fixed number of frames per second
FrameCount UI16 Total number of frames in movie
If an SWF file begins with “CWS”, the header is zipped. Unzip it. Use zlib, for example. The sample code:
SIZE GetFlashMovieSize(LPCTSTR szSWFPath)
{
SIZE size = { 0 };
HANDLE hFile = CreateFile(szSWFPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwNumberOfBytesRead;
// Read the first byte
char chFirstByte;
ReadFile(hFile,
(LPVOID)&chFirstByte,
sizeof(chFirstByte),
&dwNumberOfBytesRead,
NULL);
// Skip signature (3 bytes), version (1 byte) and file size (4 bytes)
const DWORD dwOffset = 3 + 1 + 4;
SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
char outbuffer[256];
if (67 == chFirstByte)
// Compressed
{
char buffer[256];
DWORD dwNumberOfBytesRead;
ReadFile(hFile,
buffer,
sizeof(buffer),
&dwNumberOfBytesRead,
NULL);
z_stream stream = { 0 };
stream.next_in = (Bytef*)buffer;
stream.avail_in = 256;
stream.next_out = (Bytef*)outbuffer;
stream.avail_out = 256;
inflateInit(&stream);
inflate(&stream, 1);
inflateEnd(&stream);
}
else
{
DWORD dwNumberOfBytesRead;
ReadFile(hFile,
outbuffer,
sizeof(outbuffer),
&dwNumberOfBytesRead,
NULL);
}
unsigned char nByte = outbuffer[0];
// How many bits each number occupy
unsigned char intBits = nByte >> 3;
int intTotalBits = intBits * 4 + 5;
int intTotalBytes = (intTotalBits + 7) / 8;
unsigned char * pnBytes = new unsigned char [intTotalBytes];
CopyMemory(pnBytes, outbuffer, min(intTotalBytes, sizeof(outbuffer)));
int intOffset = 5;
int intXMin =
GetIntegerFromBits(pnBytes, intOffset, intBits) / 20;
int intXMax =
GetIntegerFromBits(pnBytes, intOffset + intBits, intBits) / 20;
int intYMin =
GetIntegerFromBits(pnBytes, intOffset + 2 * intBits, intBits) / 20;
int intYMax =
GetIntegerFromBits(pnBytes, intOffset + 3 * intBits, intBits) / 20;
size.cx = intXMax - intXMin;
size.cy = intYMax - intYMin;
delete[] pnBytes;
CloseHandle(hFile);
}
return size;
}
int GetIntegerFromBits(LPVOID lpData,
int intOffset,
int intLength)
{
int intResult = 0;
LPBYTE lpBytes = static_cast(lpData);
int intBitIndex = 0;
int intSign;
for (int intBitPos = intOffset;
intBitPos < intbyteindex =" intBitPos" nbyte =" lpBytes[intByteIndex];" intlocalbitindex =" 7" intbitvalue =" ((nByte">> intLocalBitIndex) & 1);
if (0 == intBitIndex)
intSign = 1 == intBitValue ? -1 : +1;
else
{
intResult <<= 1;
intResult += intBitValue;
}
}
intResult *= intSign;
return intResult;
}