A simple .swf file and it’s below the line representation
At some point along your journey to write your own .swf files, you are
going to have to be able to read and understand the raw bits and
bytes. I created a one frame flash movie that contained only a
rectangle and saved it as Rectangle.swf. Let’s take a look at the way
the file is represented in its .swf format. Below is the hexadecimal
representation of Rectangle.swf. Let’s take a closer look…
000000 46 57 53 03 4F 00 00 00 78 00 05 5F 00 00 0F A0
000010 00 00 0C 01 00 43 02 FF FF FF BF 00 23 00 00 00
000020 01 00 70 FB 49 97 0D 0C 7D 50 00 01 14 00 00 00
000030 00 01 25 C9 92 0D 21 ED 48 87 65 30 3B 6D E1 D8
000040 B4 00 00 86 06 06 01 00 01 00 00 40 00 00 00
Every .swf file has two parts, the header block and a series of tagged data blocks. Let’s begin with the header.
HEADER
The header is always the first 21 bytes of the .swf file (true?). It
describes the file version(1,2, or 3), length of the file in bytes, the
frame size in TWIPS, frame rate in frames per second, and the frame
count.
Here is the “SWF File Reference’ description of the header:
Field
|
Type
|
Comment
|
Signature
|
UI8
|
Signature byte always ‘F’
|
Signature
|
UI8
|
Signature byte always ‘W’
|
Signature
|
UI8
|
Signature byte 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
|
The
first three bytes are the standard signature for all .swf files. They
are the ASCII values of the characters ‘F’, ‘W’, and ‘S’ in that
order. The fourth byte indicates the version of the file. Although a
file can be of version 1, 2, or 3, we will always be creating version 3
files so this value will also be fixed.
0x46 ‘F’ 0x57 ‘W’ 0x53 ‘S’ 0x03 3
The
next 4 bytes represent an unsigned 32-bit integer indicating the file
size. Here’s where it starts getting tricky and machine architecture
gets involved! The next 4 bytes are
0x4F000000
so that would imply that the file length is 1325400064 bytes, a very
large number which doesn’t make sense. What we failed to do is swap all
the bytes.
In
.swf files, bytes are swapped whenever reading words and dwords such
that a 32 bit value B1B2B3B4 is written as B4B3B2B1, and a 16 bit value
B1B2 is written as B2B1. Single bytes are written unchanged since there
is NO
bit-
swapping. The reason for this is the differences in storage and retrieval between the Mac and PC processors.
Reversing the bytes we can read the 4 bytes correctly and see that file is 79 bytes long.
0
x4F000000 0x0000004F 79
The next 9 bytes represent a data structure used in the .swf format
called a Rectangle. Here is the file description of a rectangle:
Field
|
Type
|
Comment
|
Nbits
|
nBits
= UB[5]
|
Bits in each rect value field
|
Xmin
|
SB[nBits
]
|
X minimum position for rect
|
Xmax
|
SB[nBits
]
|
X maximum position for rect
|
Ymin
|
SB[nBits
]
|
Y minimum position for rect
|
Ymax
|
SB[nBits
]
|
Y maximum position for rect
|
To understand these bytes, we need to look at the individual bits.
78 00 05 5F 00 00 0F A0 00
0111 1
000 0000 0000 0000
0101 0101 1111 000
0 0000
0000 0000 00
00 1111 1010 0000 0
000 0000
There are five fields in a rectangle structure: nBits, xmin, xmax,
ymin, ymax. The unsigned nBits field occupies the first five bits of
the rectangle and indicates how long the next four signed fields are.
Here’s
where we hit another subtle point about the .swf file
representation. Reading and writing bits is different from reading and
writing words and dwords. There is no swapping at all! This is because
when Flash is reading an n-bit field, it reads a byte at a time until
it has read all n bits. You don’t do any swapping inside of bytes so
there is no swapping at all. So the next five bits are read in order
and evaluate to 15. Although the nBit field usually varies, it appears
fixed in the header so that header has a fixed size (It may just be
because the movie dims are usually the same).
01111 15
What if nBit has a value of sixteen? This is exactly the size of a word
so do we read the following fields as words and swap bytes? No. Fields
described by bit size are always read a byte at a time. No swapping,
just read the next n bits in that order.
000000000000000
0 = xmin
010101011111000
11000 = xmax
000000000000000
0 = ymin
001111101000000
8000 = ymax
For
the header, the rectangle is used to store the movie dimensions with
xmax corresponding to the movie width and ymax corresponding to the
movie height, both in TWIPS. “What’s this TWIPS thing?” you
ask. According to whatis.com :
A
twip (twentieth of a point) is a measure used in laying out space or
defining objects on a page or other area that is to be printed or
displayed on a computer screen. A twip is 1/1440th of an inch or
1/567th of a centimeter. That is, there are 1440 twips to an inch or
567 twips to a centimeter. The twip is 1/20th of a point
, a traditional measure in printing. A point is approximately 1/72nd of an inch.
For Flash a point corresponds to a pixel, so if we convert from TWIPS to pixels, we see that our movie is 550 x 400.
Now we have looked at all of the fields of the rectangle and evaluated
them, but what about those last seven bits which are all 0’s. Well,
they were just “filled.”
0000000
= filled bits
After
the end of any structure, if the structure does not completely fill up
its last byte, then that last byte is filled with 0’s to keep the next
item byte aligned. So if the next item is a word or dword, you can read
it as such and not worry about being in the middle of a byte. In this
case, only 1 bit in the last byte is used so the last 7 bits are filled
with 0’s.
Next in the header is the frame rate, which is kind of weird. It is
supposed to be stored as a 16bit integer, but the first byte (or last
depending on how you look at it) is completely ignored. So the frame
rate is 12 fps.
0x000C 0x0C00 0x0C 12 = frame rate
Next is the frame count, which is also a 16-bit integer. So the frame count is 1.
0x0100 0x0001(byte swapping) 1 = frame count
Now we are done with the header. After the header is a series of tagged
data blocks. Here is the file description of a tag:
Short Tag
Field
|
Type
|
Comment
|
Tag
|
UB[10]
|
Tag id
|
Length
|
UB[6]
|
Length of tag
|
Long Tag
Field
|
Type
|
Comment
|
Tag
|
UB[10]
|
Tag id
|
Long Header Flag
|
UB[6]
|
Always 0x3F
|
Length
|
UI32
|
Length of tag
|
There are 2 types of tags. They are the short and long data
header. Regardless of which case you have, you begin by looking at the
first word.
0x4302 0x0243
0000 0010 01
00 0011
The
first 10 bits of the tag are the unsigned tag ID. The tag ID indicates
what type of data is to follow in the body of the data block to
follow. In this case the value of the tag ID is 9 which corresponds to
a setBackgroundColor block. (APPENDIX SHOULD HAVE ALL ID MEANINGS). The
last 6 unsigned bits of the tag indicate the length of the data block
to follow if it is 62 bytes or less. If the length of the data block is
more than 62 bytes, then this field has all 1’s and the length is
indicated in the following dword. In this situation though the field
does not have all 1’s so the field does indicate the actual length
which is 3 bytes.
0000001001
= 9 = setBackgroundColor
000011
= 3 = body length
Since we know that the length of the body is 3 bytes, let’s take a look
at it. A setBackgroundColor block only contains the 3 byte rgb color
description so we evaluate it as such. A color is its own 3 byte data
type so there is no byte swapping.
0XFFFFFF = white
The next tag is a long tag and is a defineShape tag.
0xBF00 0x00BF
0000 0000 10
11 1111
0000000010
= 3 = defineShape
111111
= body length (so we have to look at the
next dword)
0x23000000 0x00000023 35 = body length
Here is the file description of defineShape:
Field
|
Type
|
Comment
|
Header
|
RECORDHEADER
|
Tag ID = 2
|
ShapeId
|
UI16
|
ID for this character
|
ShapeBounds
|
RECT
|
Bounds of the shape
|
Shapes
|
SHAPEWITHSTYLE
|
Shape information
|
The body of a defineShape is composed of an unsigned 16-bit character
ID, a rectangle defining the bounds for the shape, and a ShapeWithStyle
structure which contains shape information.
0x0100 0x0001 1 = shape ID
Now the Rect which defines the boundaries:
70 FB 49 97 0D 0C 7D 50
0111 0
000 1111 1011 010
0 1001 1001 0111 0
000 1101 0000 110
0 0111 1101 0101 0
000
01110 = 14 = nBits
00011111011010
= 2010 = xmin /20 to covert to pixels from TWIPS 100.5
01001100101110
= 4910 = xmax 245.5
00011010000110
= 1670 = ymin 83.5
00111110101010
= 4010 = ymax 200.5
000
= fill bits
The ShapeWithStyle structure has five parts. A fill style array, a line
style array, a nFillBits field, a nLineBits field, and an array of
shape records. Here is the file description:
Field
|
Type
|
Comment
|
FillStyles
|
FILLSTYLEARRAY
|
Array of fill styles
|
LineStyles
|
LINESTYLEARRAY
|
Array of line styles
|
NumFillBits
|
nFillBits
= UB[4]
|
Number of fill index bits
|
NUML
ineBits
|
nLineBits
= UB[4]
|
Number of line index bits
|
ShapeRecords
|
SHAPEREC[one or more]
|
Shape records - see below
|
A fill style array itself has three fields. The first field is an 8 bit
integer count which indicates how many fill styles are in the
array. This count works similar to the tag’s length field in that if it
is all 1’s, you have to look at the next 16-bits to get the actual
length. Here is the file description:
Field
|
Type
|
Comment
|
FillStyleCount
|
count
= UI8
|
Count of fill styles
|
FillStyleCountExtended
|
If count
= 0xFF count
= UI16
|
Extended count of fill styles. Supported only for Shape2 and Shape3.
|
FillStyles
|
FILLSTYLE[count
]
|
Array of fill styles
|
In this case, the 8 bit count is equal to 0 so there is nothing to follow it.
0x00 = 0 = count This is the end of the fill style array because it has no elements
A line style array is exactly the same as a fill style array except it stores line styles. Here is the file description:
Field
|
Type
|
Comment
|
LineStyleCount
|
count
= UI8
|
Count of line styles
|
LineStyleCountExtended
|
If count
= 0xFF count
= UI16
|
Extended count of line styles
|
LineStyles
|
LINESTYLE[count
]
|
Array of line styles
|
0x01 = 1 = count So there is one line style in the array.
A line style has two parts, an unsigned 16-bit integer indicating the
width of a line in TWIPS, and a color. Here is the file description:
Field
|
Type
|
Comment
|
Width
|
UI16
|
Width of line in twips
|
Color
|
RGB (Shape1 or Shape2)
RGBA (Shape3)
|
Color value including alpha channel information for Shape3s
|
The
color in this case is a 24-bit RGB, but if we were doing a
defineShape3, it would be a 32-bit RGBA where alpha is the transparency
of the color.
0x1400 0x0014 = 20 = width = 1 pixel
0x000000 = RGB = black
Back to the ShapeWithStyle, the nFillBits field is 4 bits, as is the nLineBits.
0x0 = 0 = nFillBits 0x1 = 1 = nLineBits
Now for the array of shape records. There are three types of shape records. Here are the file descriptions:
Shape Record Type 0
Field
|
Type
|
Comment
|
TypeFlag
|
UB[1] = 0
|
Non-edge record flag
|
EndOfShape
|
UB[5] = 0
|
End of shape flag
|
Shape Record Type 1
Field
|
Type
|
Comment
|
TypeFlag
|
UB[1] = 0
|
Non-edge record flag
|
StateNewStyles
|
newStyles
= UB[1]
|
New styles flag. Used by DefineShape2 and DefineShape3 only.
|
StateLineStyle
|
lineStyle
= UB[1]
|
Line style change flag
|
StateFillStyle0
|
fillStyle0
= UB[1]
|
Fill style 0 change flag
|
StateFillStyle1
|
fillStyle1
= UB[1]
|
Fill style 1 change flag
|
StateMoveTo
|
moveTo
= UB[1]
|
Move to flag
|
MoveBits
|
If moveTo
nMoveBits
= UB[5]
|
Move bit count
|
MoveDeltaX
|
If moveTo
UB[nMoveBits
]
|
Delta X value
|
MoveDeltaY
|
If moveTo
UB[nMoveBits
]
|
Delta Y value
|
Fill0Style
|
If fillStyle0
UB[nFillBits
]
|
Fill 0 Style
|
Fill1Style
|
If fillStyle1
UB[nFillBits
]
|
Fill 1 Style
|
LineStyle
|
If lineStyle
UB[nLineBits
]
|
Line Style
|
FillStyles
|
If newStyles
FILLSTYLEARRAY
|
Array of fill styles
|
LineStyles
|
If newStyles
LINESTYLEARRAY
|
Array of line styles
|
Shape Record Type 2
Field
|
Type
|
Comment
|
TypeFlag
|
UB[1] = 1
|
This is an edge record
|
EdgeRecord
|
line-hei
分享到:
Global site tag (gtag.js) - Google Analytics
|
相关推荐
1 Computers and Programs 1 1.1 The Universal Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Program Power . . . . . . . . . . . . . . . . . . . . . . . . . . ....
1 S.7 The BSC and the Gaussian Channel Model . . . . . . . . . . . . . 25 1.6 Memoryless Channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.7 Simulation and Energy Considerations ...
Knowledge representation learning (KRL) aims to represent entities and relations in knowledge graph in low-dimensional semantic space, which have been widely used in massive knowledge-driven tasks....
l CPU's from the 8086/8088 to the Pentium III and Athlon l Real, protected and virtual models l Windows and plug&play devices l CPU Clones from all major manufacturers l Chipsets and support chips...
Your program’s input and output . . . . . . . . . . . . . . . . . . . . . . . . Debugging an already-running process . . . . . . . . . . . . . . . . . . . Killing the child process . . . . . . . . . ...
4.6 Your Program’s Input and Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Debugging an Already-running Process . . . . . . . . . . . . . . . . . . . . . . . . 4.8 Killing the ...
3.2.8 Prior and posterior value of the penalty function . . . . . . 24 3.3 Discrete form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 4 Sequential data ...
PEP 519: Adding a file system path protocol PEP 495: Local Time Disambiguation PEP 529: Change Windows filesystem encoding to UTF-8 PEP 528: Change Windows console encoding to UTF-8 PEP 520: ...
2.2.5 Expanding the Bit Representation of a Number . . . . . . . . . . . . . . . . . . . . 49 2.2.6 TruncatingNumbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 2.2.7 ...
The Way to Go,: A Thorough Introduction to the Go Programming Language 英文书籍,已Cross the wall,从Google获得书中源代码,分享一下。喜欢请购买正版。 目录如下: Contents Preface......................
2 Kronecker products, the vec operator and the Moore-Penrose inverse 31 1Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2The Kronecker product . . . . . . . . . . . . . . . ...
the output weights file from training for a testing run), and the output weights file which gives you weight values after the last iteration. Note that the pattern files have values for each ...
(3) File extensions and packages:.......................................................................14 2.2 Go Environment variables...................................................................
We are often asked if it is possible to run an UltraEdit macro or script on a file from the command line. The answer is yes - and it's not only possible, it's extremely simple! Using find/replace ...
One of the strong features of java is that it is follows a OOPs concept, and one of the feature of OOP in java is that, we can assign a subclass object or variable to the variable of the superclass ...
The success of machine learning algorithms generally depends on data representation, and we hypothesize that this is because different representations can entangle and hide more or less the different ...
This is a great introduction to the Semantic Web and its associated knowledge-representation standards. More important, the book shows how to use the standards, and does so in a lively and lucid way.