A bitmap is a character like any other, with a 16-bit ID. It is never placed on the stage by itself: a shape shows it through a bitmap fill. There are two families of bitmap tag, JPEG and lossless, and from SWF 3 both may carry alpha. Rows run top to bottom in every kind. In this format every JPEG tag holds JPEG data.
DefineBits (6)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | CharacterID | The character ID |
| 2 | to the end | bytes | JPEGData | A JPEG image without its tables |
The quantisation and Huffman tables are in the movie’s one JPEGTables tag, shared by every DefineBits. To decode, put the tables before the image data.
JPEGTables (8)
The encoding tables (DQT and DHT markers) as a JPEG stream from FF D8 to
FF D9, used by every DefineBits in the movie. A movie has at most one.
Some movies’ JPEGTables is only FF D8 FF D9, with no tables.
DefineBitsJPEG2 (21, SWF 2)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | CharacterID | The character ID |
| 2 | to the end | bytes | ImageData | A JPEG with its own tables |
DefineBitsJPEG3 (35, SWF 3)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | CharacterID | The character ID |
| 2 | 4 | UI32 | AlphaDataOffset | The size of ImageData |
| 6 | AlphaDataOffset | bytes | ImageData | A JPEG with its tables |
| … | to the end | bytes | BitmapAlphaData | zlib-compressed alpha, one byte a pixel |
Whether Flash Player premultiplies the JPEG’s colours by this alpha is not confirmed; the explorer does not divide them out.
JPEG data in this format
- The JPEG data may start with an erroneous header,
FF D9 FF D8, before the real start of image marker. Skip it. - Flash wrote DefineBitsJPEG2 and 3 data as two streams back to back: one with only
the tables, then the image,
FF D8tablesFF D9 FF D8imageFF D9. Browsers do not take this as an image, so a reader has to join the streams or decode them itself; the explorer decodes JPEG itself. That Flash wrote it this way is known from files, not from the specification. - The explorer decodes baseline and progressive JPEG, with and without JPEGTables.
DefineBitsLossless (20, SWF 2)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | CharacterID | The character ID |
| 2 | 1 | UI8 | BitmapFormat | 3 8-bit colour-mapped, 4 15-bit RGB, 5 24-bit RGB |
| 3 | 2 | UI16 | BitmapWidth | Width in pixels |
| 5 | 2 | UI16 | BitmapHeight | Height in pixels |
| 7 | 1 | UI8 | BitmapColorTableSize | Format 3 only: the number of colours minus 1 |
| 7 or 8 | to the end | bytes | ZlibBitmapData | The zlib-compressed pixels |
Decompressed, the data is:
- Format 3, COLORMAPDATA: the colour table, RGB × (BitmapColorTableSize + 1), then one UI8 index a pixel, each row padded to a multiple of 4 bytes.
- Format 4, BITMAPDATA of PIX15: two bytes a pixel, a reserved bit then 5 bits each of red, green and blue, read as bits from the first byte; rows padded to 4 bytes.
- Format 5, BITMAPDATA of PIX24: four bytes a pixel, a reserved byte then red, green and blue.
DefineBitsLossless2 (36, SWF 3)
The same fields as DefineBitsLossless, with alpha:
- Format 3: the colour table is RGBA, four bytes a colour.
- Format 5: ARGB, four bytes a pixel, alpha first.
- Format 4 is not used.
The colour values are premultiplied by alpha, as Flash Player and Ruffle read them; the explorer divides them back out to show the bitmap.
Decoding, step by step
- DefineBits: take the JPEGTables stream, drop its end marker and the image’s start marker, and decode the two as one JPEG.
- DefineBitsJPEG2 and 3: skip any erroneous header, join the table and image streams, and decode.
- JPEG3: inflate BitmapAlphaData (zlib) and take one alpha byte a pixel, rows top to bottom.
- Lossless: inflate ZlibBitmapData, then read the colour table if any and the rows, skipping each row’s padding to 4 bytes.
Bitmap tags from later versions
| Tag | SWF | Fields |
|---|---|---|
| DefineBitsJPEG4 (90) | 10 | UI16 CharacterID, UI32 AlphaDataOffset, UI16 DeblockParam (8.8), the image data, then zlib alpha. It has no place in a SWF 1 to 5 movie |
From SWF 8, the JPEG tags of later formats may also hold PNG or GIF images; in this format they hold only JPEG.