A ZWS movie starts with a 17-byte header that is not compressed. Its first 8 bytes have the layout every SWF starts with: the signature, the SWF version and the length of the movie once decompressed. Then come two things only ZWS has: the length of the compressed data and the 5 LZMA property bytes. The rest of the movie header, the frame size, frame rate and frame count, is the first thing inside the LZMA data. Offsets for those fields are offsets in the decompressed data: an 8-byte header followed by the decoded bytes, so the frame size is at offset 8, as in an uncompressed movie.
Fields
All numbers are little-endian.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 3 | UI8[3] | Signature | ZWS (5A 57 53): the movie is LZMA-compressed. |
| 3 | 1 | UI8 | Version | The SWF version, 13 or later. |
| 4 | 4 | UI32 | FileLength | The length of the whole movie uncompressed, with an 8-byte header counted. Not the size of the file. |
| 8 | 4 | UI32 | CompressedLength | The bytes of LZMA data after the 17-byte header; the 5 property bytes are not counted. See Compression. |
| 12 | 1 | UI8 | Properties | lc + 9 × (lp + 5 × pb); 5D is the usual value. See LZMA properties. |
| 13 | 4 | UI32 | DictionarySize | The LZMA dictionary size in bytes. |
| 17 | … | LZMA data | The rest of the file. |
In the decompressed data:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 8 | 9 to 17 | RECT | FrameSize | The stage in twips; Xmin and Ymin are normally 0. |
| after | 2 | UI16 (8.8) | FrameRate | Frames a second: the first byte is the fraction (÷ 256), the second the whole part. |
| after | 2 | UI16 | FrameCount | The number of frames on the main timeline. |
| after | … | Tags | The tags, to the End tag. |
The decompressed data starts at the frame size, so the 9 header bytes from offset 8 to 16 of the file, CompressedLength and the properties, are not part of the movie. The explorer puts the first 8 bytes of the file in front of the decoded bytes, which gives the same offsets as an uncompressed movie.
Signature
The three bytes ZWS mark a movie compressed with LZMA. The other SWF
signatures are FWS (uncompressed) and CWS (zlib); the
letters WS stay the same in all three. Unlike CWS, a ZWS file is not the
same movie with one byte changed and the body compressed: it also has the 9 extra
header bytes at offset 8.
Version
The SWF version the movie was written for. It decides which tags and actions the player expects. Flash Player 11.0, SWF 13, introduced LZMA compression (PRONOM fmt/770: “Version 13 introduced the option of using LZMA compression”), so a ZWS movie is SWF 13 or later. 7-Zip raises the version to at least 13 when it compresses a movie with LZMA. A ZWS file whose header gives a lower version would not play in Flash Player; the explorer still opens it and notes the mismatch. It also notes a version above 60 as newer than any known.
The versions a ZWS movie can have:
| SWF | Flash Player (or AIR) | Released | Authoring tool |
|---|---|---|---|
| 13 | Flash Player 11.0 (AIR 3.0) | October 2011 | |
| 14 | 11.1 (AIR 3.1) | November 2011 | |
| 15 | 11.2 (AIR 3.2) | March 2012 | Flash CS6 (2012) |
| 16 | 11.3 (AIR 3.3) | June 2012 | |
| 17 | 11.4 (AIR 3.4) | August 2012 | |
| 18 | 11.5 (AIR 3.5) | November 2012 | |
| 19 | 11.6 (AIR 3.6) | February 2013 | Flash Professional CC (June 2013) |
| 20 | 11.7 (AIR 3.7) | April 2013 | |
| 21 | 11.8 (AIR 3.8) | July 2013 | |
| 22 | 11.9 (AIR 3.9) | October 2013 | |
| 23 | 12 (AIR 4.0) | late 2013 or January 2014 (sources differ) | |
| 24 to 43 | 13 to 32, one SWF version a major release (AIR 13 to 32) | April 2014 to 2018–2020 | Flash Professional CC 2014 and 2015; Adobe Animate (from February 2016) |
| 44 | Harman AIR 33.1 | ||
| 50 | Harman AIR 50 | ||
| 51 | Harman AIR 51 | 2024 onwards |
The last global Flash Player build was 32.0.0.465, in December 2020. The last edition of the specification is for SWF 19; later versions added no documented structures.
FileLength
The length of the movie when it is not compressed, counting an 8-byte header, as in every SWF. It is not the size of the ZWS file. Decoding the LZMA data should give exactly FileLength − 8 bytes. The LZMA data carries no size of its own, so this is the number that tells the decoder when to stop; the explorer stops there whether or not an end marker follows.
CompressedLength, the next field, counts the compressed bytes after offset 17. The explorer shows the bytes the decoder used as the compressed body, and any bytes after them as “After the compressed data”.
FrameSize
The first field inside the decompressed data, at offset 8: a RECT giving the stage in twips, twentieths of a pixel. A RECT is bit-packed: a 5-bit Nbits, then Xmin, Xmax, Ymin and Ymax as signed Nbits-bit values, padded to a whole byte. So the field is 9 bytes for a stage up to 1,638 pixels and grows with larger values, up to 17 bytes.
Flash writes a 550 × 400 pixel stage as these 9 bytes:
78 00 05 5F 00 00 0F A0 00
0x78is01111000: the first 5 bits,01111, give Nbits = 15.- The next 15 bits are Xmin = 0, then Xmax = 11,000 (550 px × 20), then Ymin = 0 and Ymax = 8,000 (400 px × 20).
- 5 + 4 × 15 = 65 bits, padded to 72: 9 bytes.
FrameRate
Frames a second, as 8.8 fixed point stored as a little-endian UI16: the first byte is
the fraction in 256ths, the second the whole number. 12 frames a second is
00 0C, 24 is 00 18 and 60 is 00 3C. The fraction
lets a movie run at, for example, about 29.97 frames a second
(F8 1D).
FrameCount
The number of frames on the main timeline: the number of ShowFrame tags it holds. Sprites have frame counts of their own, in their DefineSprite tags. An ActionScript 3 application often has one or two frames and builds everything else in code. The tags follow at once.