Friday, October 24, 2008

Introduction. SWF structure.

I think everybody knows that awkward situation when you're asked a "wrong" question because the person who asks knows nothing about the topic. It's difficult to understand what to start answer from in such a situation. That's why I'll begin... at the very beginning.

Introduction

When saying Flash, we can mean absolutely different things even within the bounds of web-technology terms. Not to get confused, I'll use the following terms:

  • Flash – the technology of web-animation on the whole;
  • Flash player – program, ActiveX library which displays flash;
  • Standalone Flash player – application (exe file) displaying flash;
  • Flash IDE, Adobe Flash, Flash Professional – development environment provided by Adobe Systems (former Macromedia);
  • FLA – project (source) animation file for Flash IDE;
  • Movie – an integral web-animation at the development stage;
  • SWF – result animation file.
  • So, when loading a web page with flash animation, the following processes take place: web-browser detects an embedded flash animation in an HTML markup, creates and object of flash-player and indicate what file needs to be displayed. Flash player loads SWF file and begins to display it if possible. Due to this principle of work, flash player can display so called preloaders, reproduce streaming audio and video (for example, YouTube) without loading SWF fully.

    SWF structure

    File format is described in "SWF file format specification" document, which can be downloaded at Adobe.com. Documentation is usually issued some months after the release of a new version of flash player. At the moment, flash player v.10 is already released, but specification document is not renewed and contains specification of version 9. One can find specifications about almost everything I explain here, but the matter is that "almost", but not everything :)

    Basic structure of SWF doesn't depend on version, that's why SWF always has Header+Body structure. Body consists of records which are called tags in specification.

    To describe data structure, I'll use Object Pascal syntax.

    Header

    Header contains main information about SWF. It can be described in this way:

    TSWFHeader = packed record
    SIGN: array [0..2] of AnsiChar;
    Version: byte;
    FileSize: LongWord;
    MovieRect: TRect;
    FPS: word;
    FramesCount: word;
    end;

  • The first parameter is SIGN. CWS value means that this file is packed using ZLib compression method, not an FWS.
  • Version – version of file format.
  • FileSize – size of UNPACKED file in bytes.
  • MovieRect – size of displayed image in twips (1px = 20twips). I should note that in fact SWF and graphic objects can't be larger than $ffff/ 20 = 3276 px. I haven't seen swf with top-left value less or more than 0. Nevertheless, having set these values in my tests, I made sure that these values are really taken into account. It's worth noting that the specified rectangle is a place given by browser. When opening SWF in a standalone player, sometimes one can see "decorations behind the scenes".
  • FPS (frames per second) – value in format 8.8 fixed, i.e. for human perception this value is Result := FPS shr 8 + (FPS and $FF) / ($FF+1);
  • FramesCount– frames number. As a rule, SWF always has at least one frame, but it's possible to create SWF without frames if this file is used as a library for other SWFs.
  • SWF compression

    To reduce file size, Macromedia has used two approaches.

    The first one consists of that bit-by-bit compression method is used for saving numbers. It looks like this. Let's presume we need to save a size of rectangle, i.e. four numbers of integer type. At a simple record it will be 4 * 4 bytes = 16 bytes. At recording to SWF, the number of bits needed for coding the largest value is recorded to the first 5 bit, and then these 4 values in bit representation with a specified bit length. For example, it's necessary to save coordinates (0,0 – 100, 100) or in twips (0,0 – 2000,2000). In bit representation number 2000 = 11111010000 (11 bit + 1 for a sign). We have (5 + 4 * 12) / 8 = 7 byte (almost 2 times less). This approach leads to the fact that some identical tags can have different size. It also applies to Header.

    The second approach is using ZLib compression method both for the whole SWF and for separate tags.

    When a file is compressed, first three parameters of a Header (8 bytes) are not compressed, but the rest are compressed. This explains why it's impossible to read an SWF header only with one read method.

    2 comments:

    1. Grabets, thanks for the great post, you are one of the very few person who combine the Flash and delphi world together, hope you continue your work.

      ReplyDelete
    2. Good day Oleg.

      I am an enthusiast of Delphi and I'm starting to get to the World of Flex and I wonder if there are studies for his company to create a pattern of direct connection between Delphi and Flex applications of databases through the protocol AMF3, thus replacing PHP as an intermediate layer.

      Thank you.

      ReplyDelete