How to get a width and a height from an SWF

Artem Razin
May 2, 2007

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):

FieldTypeComment
SignatureUI8Signature byte always 'F'
SignatureUI8Signature byte always 'W'
SignatureUI8Signature byte always 'S'
VersionUI8Single byte file version (e.g. 0x04F for SWF 4)
FileLengthUI32Length of entire file in bytes
FrameSizeRECTFrame size in twips
FrameRateUI16Frame delay in 8.8 fixed number of FPS
FrameCountUI16Total number of frames in movie

If an SWF file begins with "CWS", the header is compressed (zipped). You should unzip it using something like zlib.

Here’s the sample code in C++:

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; 
        char chFirstByte;
        ReadFile(hFile, (LPVOID)&chFirstByte, sizeof(chFirstByte), &dwNumberOfBytesRead, NULL); 
 
        const DWORD dwOffset = 3 + 1 + 4;
        SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN); 
 
        char outbuffer[256]; 
 
        if (chFirstByte == 'C') // Compressed
        {
            char buffer[256];
            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, Z_SYNC_FLUSH); 
            inflateEnd(&stream);
        }
        else
        {
            ReadFile(hFile, outbuffer, sizeof(outbuffer), &dwNumberOfBytesRead, NULL);
        } 
 
        unsigned char nByte = outbuffer[0]; 
        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<LPBYTE>(lpData); 
 
    int intBitIndex = 0;
    int intSign; 
 
    for (int intBitPos = intOffset; intBitPos < intOffset + intLength; intBitPos++, intBitIndex++)
    {
        int intByteIndex = intBitPos / 8;
        __int8 nByte = lpBytes[intByteIndex];
        int intLocalBitIndex = 7 - intBitPos % 8;
        int intBitValue = ((nByte >> intLocalBitIndex) & 1); 
 
        if (intBitIndex == 0)
            intSign = (intBitValue == 1) ? -1 : +1;
        else
        {
            intResult <<= 1;
            intResult += intBitValue;
        }
    }
 
    intResult *= intSign;
    return intResult;
}

This method gives you the movie dimensions in pixels by extracting values from the SWF file header.