The SWF (pronounced 'swiff') file format was designed from the ground up to deliver graphics and animation over the Internet. The SWF file format was designed as a very efficient delivery format and not as a format for exchanging graphics between graphics editors. It was designed to meet the following goals:
- On-screen Display—The format is primarily intended for on-screen display and so it supports anti-aliasing, fast rendering to a bitmap of any color format, animation and interactive buttons.
- Extensibility—The format is a tagged format, so the format can be evolved with new features while maintaining backwards compatibility with older players.
- Network Delivery—The files can be delivered over a network with limited and unpredictable bandwidth. The files are compressed to be small and support incremental rendering through streaming.
- Simplicity—The format is simple so that the player is small and easily ported. Also, the player depends upon only a very limited set of operating system functionality.
- File Independence—Files can be displayed without any dependence on external resources such as fonts.
- Scalability—Different computers have different monitor resolutions and bit depths. Files work well on limited hardware, while taking advantage of more expensive hardware when it is available.
- Speed—The files are designed to be rendered at a high quality very quickly.
The following document describes the file format in detail.
Basic Concepts
Container Format
SWF files are stored in files with the extension .swf and currently for historical reasons the MIME type is application/x-shockwave-flash. SWF files are binary files stored as 8-bit bytes. The container format consists of a header block with the structure shown below.
Field | Type | Comment |
Signature | UI8 | Signature byte 1 - always 'F' |
Signature | UI8 | Signature byte 2 - always 'W' |
Signature | UI8 | Signature byte 3 - always 'S' |
Version | UI8 | Single byte file version |
File Length | UI32 | Length of entire file in bytes |
Frame Size | RECT | Frame size in TWIPS |
Frame Rate | UI16 | Frame delay in 8.8 fixed number of frames per second |
Frame Count | UI16 | Total number of frames in movie |
Following the header are a series of tagged data blocks. Each data block has a tag type (stag) and a length. There is both a short and long tag format. Short tags are used for blocks with 62 bytes of data or less and large tags can be used for any size block. A short tag has 9 bits used for the block type and 6 bits used for a block length in number of bytes. If a block is 63 bytes or longer, it should be stored in a long tag which consists of a short tag whose length is 0x3f and is followed by a 32-bit length.
The following tables show the structure of both short and long tag record headers.
Short header - for records less than 63 bytes in length
Field | Type | Comment |
Tag | UB[10] | Tag id |
Length | UB[6] | Length of tag |
Long header - for records 63 bytes in length or greater
Field | Type | Comment |
Tag | UB[10] | Tag id |
Long Header Flag | UB[6] | Always 0x3F |
Length | UI32 | Length of tag |
Any program parsing a SWF file can skip over blocks it does not understand. Data blocks can point to offsets within the block, but they should never point to an offset in another block. This enables tags to be removed, inserted, or modified by tools that process a SWF file. With some network transports like RealFlash, data blocks can be reordered and delivered with different priorities.
Currently, many useful block types are defined. Tag numbers 0-511 are reserved for future use. Tag numbers 512-1023 are reserved for use by third party applications. For more information on developing extension mechanisms, see the extension mechanism section.
Types of Tags
Definition tags are used to add character information to the dictionary. Definition tags define data that can be reused in a file like shapes, bitmaps, buttons, text, fonts and sounds. Control tags manipulate characters and provide administrative functions. For example, control tags are used to move objects on the screen, show frames, and start sounds. For information on specific tags, see the Tag Reference section.
Tag Ordering and Streaming
Tags can occur in the file in any order. Definition tags must occur in the file before any control tags that refer to the character that is defined. The order of control tags defines the order of the animation.
This ordering of tags is how the SWF file format supports streaming. The rule is that a given tag should only depend on tags that come before it. A tag should never depend on a tag that comes later in the file.
The End tag should be used at the end of the file to indicate the file's end.
Characters and the Dictionary
In order to support streaming and references between tags, SWF uses the concept of characters and a dictionary of characters that have been encountered so far in a file. A character has a 16-bit numeric name. Every character in a file must have a unique name. Typically, the first character is #1, the second character is #2 and so on. Character #0 is special and considered a null character.
Characters are entered into the dictionary when a define tag is encountered in the .swf file. Characters are looked up in the dictionary based on the character identification number.
Display List
Conceptually, the SWF file format can be considered as two interleaved streams of data. The definition stream adds characters to the dictionary and the control stream performs operations on the display list using the characters that have been defined in the dictionary.
In SWF 1 and 2, the display list was a flat list of the objects that are present on the screen at any given point in time. For SWF 3, this list has been extended to a hierarchical list where an element on the display can have a list of child elements.
Objects on the display list are referred to by a depth number. The object at depth 0 is the bottom of the stacking order. Only one object can exist at any given depth.
There are three basic operations on the display list:
- Place an object—Place an character on at a given depth level using a specified transform.
- Move an object—Modify the object at the given depth level. Both the transform and the character can be modified.
- Remove an object—Remove the object at a given depth number from the display.
Note that for SWF 1 and 2, the only operations are Place and Remove. Move was added to support sprites and as a size optimization for SWF 3.
Numbers and Coordinates
SWF uses integers and fixed point numbers for all of its coordinates and transformation matrices. The coordinate space is defined by integer coordinates. This coordinate space can be mapped to the display in any way that a player might want. By convention, coordinates are specified where one unit equal 1/1440 inches. On a typical 72 dpi display this is equivalent to saying that a single pixel is divided into 20 units. This choice of units provides a good compromise between giving a high resolution for zooming in and precise placement of objects. A higher resolution would increased the file size because of the extra bits needed for precision.
Transforms
Matrices—Object positioning is specified by a standard 2x3 transformation matrix using 16.16 fixed point numbers for the first four elements and integers for the last two elements.
Color Transforms—SWF uses color transforms to perform effects like fading in or out from an object on the display. The color transform consists of a simple linear equation that is applied to each color element of an object.
Ratio—For some objects like morphed shapes, a 16-bit ratio is used to control what point in the morph should be displayed. The ratio is also used to track the lifetime of sprite objects.
Clip depth—An object on the SWF display list can be used as a clipping path for range of objects. This is controlled by the clip depth field for Place object.
Processing a SWF File
The model for processing a stream is that all tags are processed in a stream until a ShowFrame tag is encountered. At that point, the display list is copied to the screen and the player is idle until it is time to process the next frame.
A SWF file is divided into numbered frames by ShowFrame tags. Frame 1 is defined by performing all the control operations before the first ShowFrame tag. Frame 2 is defined by performing all the control operations before the second ShowFrame tag and so on.
File Compression Strategy
Since SWF files are frequently delivered over a network connection, it is important that they be as compact as possible. There are several techniques that are used to accomplish this:
- Reuse—The structure of the character dictionary makes it very easy to reuse elements in a SWF file. For example, a shape, button, sound, font, or bitmap can be stored in a file once and referenced many times.
- Compression—The contents of tags are compressed. SWF supports a variety of compression techniques. Bitmaps can be compressed with JPEG or a PNG-like zlib compression. Sound is compressed with various levels of ADPCM compression. Shapes are compressed using a very efficient delta encoding scheme.
- Bit Packing—Whenever possible, numbers are packed into the smallest possible number of bits for a particular value. Coordinates are commonly stored using variable-sized bit fields, where a few bits are used to indicate how many bits are needed by subsequent values. See RECT for an example.
- Default values—Some structures like matrices and color transforms have common fields that are used more often than others. For example, for a matrix, the most common field is the translation field. Scaling and rotation are less common. Therefore if the scaling field is not present, it is assumed to be 100%. If the rotation field is not present, it is assumed that there is no rotation. This use of default values helps to minimize file sizes.
- Change Encoding—As a rule, SWF files just store the changes between states. This is reflected in shape data structures and in the place/move/remove model used by the display list.
- Shape Data Structure—The shape data structure uses a unique structure to minimize the size of shapes and to render anti-aliased shapes very efficiently on the screen.
Note that although the individual components of a SWF file are compressed, there is no overall compression applied to the .swf file. This makes it possible for a player to process the file structure directly out of RAM without decompressing it. Various elements of the file such as bitmaps, shapes and sounds can be decompressed as they are needed.
Extension Mechanism
In order to let applications define their own tag types, it is possible to define an AppExtension tag that contains the name of the application functionality being implemented and a tag range that describe what tags will be used by this extension set. The extension sets should be similar to a MIME type where they take the form of the following string:
<company name>/<extension set>
For the entire file, these tag types will be interpreted in the context of the named extension. Applications should be able to remap the tag range for a particular file to avoid conflicts between two extension sets.
The extension must be in the 512-1023 tag type range.
Sample SWF Files
The following section shows a SWF file. Syntax is displayed in monospaced font. Explanations of the syntax appear in normal font.
***** Dumping SWF File Information ***** ----- Reading the file header ----- FWS File version 3 File size 741 Movie width 550 Movie height 400 Frame rate 12 Frame count 10
The file header shows much information. FWS indicates that the file is a SWF file; its version is 3.0 file. The file size is 741 bytes. The movie width is 550; its height is 400 pixels. The frame rate is 12 frames per second; there are ten frames in this movie.
----- Reading movie details ----- <----- dumping frame 0 file offset 21 ----->
The offset of Frame 0 is 21 bytes into the file.
tagLen 3: tagSetBackgroundColor RGB_HEX ffffff
TagLen specifies the actual length of the tag, in this case, 3 bytes (ffffff). .This tagSetBackgroundColor sets the background color to white.
tagLen 2: tagDoAction action code 7 stop action code 0
Pauses the frame. (DoAction's action is Stop. Action code 0 means that there are no more actions.)
tagLen 32: tagDefineShape tagid 1
Defines the first shape.
tagLen 10: tagPlaceObject2 flags 1 depth 26 tag 1 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [000010a4 00000410]
Inserts the first shape (tag 1) on the display list. The object's position on the stage is defined by the matrix.
tagLen 201: tagDefineShape2 tagid 2 tagLen 76: tagDefineShape tagid 3 tagLen 190: tagDefineShape2 tagid 4 tagLen 33: tagDefineButton2 tagid 5
Defines more shapes and a button.
tagLen 15: tagPlaceObject2 flags 2 depth 26 tag 5 pos matrix hex [ a_fixed b_fixed] = [0004dbd3 00000000] [ c_fixed d_fixed] [00000000 0004dbd3] [tx_fixed ty_fixed] [00000600 00000a1c]
Inserts the button (tag 5) on display list.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 1 file offset 627 -----> tagLen 2: tagRemoveObject2 depth 2
Removes button from the display list.
tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [000012ea 00000690]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays display list contents on the screen.
<----- dumping frame 2 file offset 643 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [00001530 00000910]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 3 file offset 655 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [00001776 00000b90]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 4 file offset 667 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [000019bc 00000e10]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 5 file offset 679 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [00001c03 00001090]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 6 file offset 691 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [00001e49 00001310]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 7 file offset 703 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [0000208f 00001590]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 8 file offset 715 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [000022d5 00001810]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 9 file offset 727 -----> tagLen 8: tagPlaceObject2 flags 1 depth 26 pos matrix hex [ a_fixed b_fixed] = [00010000 00000000] [ c_fixed d_fixed] [00000000 00010000] [tx_fixed ty_fixed] [0000251b 00001a90]
Moves square left to right, top to bottom, diagonally on the stage.
tagLen 0: tagShowFrame
Displays contents of display list on the screen.
<----- dumping frame 10 file offset 739 -----> tagLen 0: tagEnd
tagEnd indicates the end of the file.
***** Finished Dumping SWF File Information *****