I am working on SWF file decompiling according to the swf_file_format_spec_v9.pdf provided by adobe these days. After I decompiled the first 8 bytes data of a sample SWF file. I found that the FrameSize is defined as a RECT structure below:
RECT Field Type Comment 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
I have to read the first 5 bits from a ByteArray contains 9 bytes as the Nbits, then read 15 bits each time to get the positions for the rect.
That’s really a hard work for me to get bits from the binary data, I have never do such thing before.
I wrote a lot of codes, and tried many ways to get what I want . But I found all of them are not “beautiful” enough. At last, I got this simple class to catch what I want.
This class is used to read any amount,less than 53, bits from a given ByteArray.
package com.edison.utils
{
import flash.utils.ByteArray;
public class BitsReader
{
private var _source:ByteArray;
private var maxBitsLength:uint;
private const BYTE_LEGNTH:uint = 8;
private const NUMBER_LENGTH:uint = 53;
private const INT_LENGTH:uint = 32;
public function get source():ByteArray
{
return _source;
}
private var _position:uint = 0;
public function get position():uint
{
return _position;
}
public function set position(value:uint):void
{
if(value > maxBitsLength)
{
_position = maxBitsLength;
}
else
{
_position = value;
}
}
public function BitsReader(source:ByteArray)
{
maxBitsLength = source.length*BYTE_LEGNTH;
_source = source;
}
public function read(length:uint):Number
{
//make sure the length of the return value is less or equal than the length of Number;
if(length> NUMBER_LENGTH)
{
length = NUMBER_LENGTH;
}
//make sure the length of the return value if less or equal the amount of all the bits.
if(length>maxBitsLength)
{
length = maxBitsLength;
}
//if there is not enought bits to return, return all the left.
if(length>maxBitsLength - position)
{
length = maxBitsLength - position;
}
var result:Number = 0;
var byteLength:uint = (position+length)/BYTE_LEGNTH;
var leftBitsLength:uint = (position+length)%BYTE_LEGNTH;
var startByteIndex:uint = 0;
var extractFromFirstByte:Boolean = false;
if(position!=0)
{
startByteIndex = Math.ceil(position/BYTE_LEGNTH)-1;
extractFromFirstByte = true;
}
source.position = startByteIndex;
var byte:uint = 0;
for(var i:uint = startByteIndex ;i<byteLength;i++)
{
result <<= BYTE_LEGNTH;
byte = source.readUnsignedByte();
if(extractFromFirstByte)
{
result ^= (byte<< (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH)) >>> (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH) ;
position += (BYTE_LEGNTH - position%BYTE_LEGNTH);
extractFromFirstByte = false;
}
else
{
result ^= byte;
position += BYTE_LEGNTH;
}
}
result <<= leftBitsLength;
byte = source.readUnsignedByte();
result ^= byte>>(BYTE_LEGNTH-leftBitsLength);
position += leftBitsLength;
return result;
}
}
}
This is a sample of BitsReader, quite easy.
var rect:ByteArray = new ByteArray(); uncompressedData.readBytes(rect,0,9); var bits:BitsReader = new BitsReader(rect); bits.read(5); bits.read(15); trace(”file width: “,bits.read(15)/20,”pixel”); bits.read(15); trace(”file height: “,bits.read(15)/20,”pixel”);
Now, you can have a try with this class
.

July 15th, 2008
Ntt.cc
Posted in
Tags: 
RSS Feed
Email Feed
BitsReader:从ByteArry中读取一定个数的二进制位…
I am working on SWF file decompiling according to the swf_file_format_spec_v9.pdf provided by adobe these days. After I decompiled the first 8 bytes data of a sample SWF file. I found that the FrameSize is defined as a RECT structure bel…
[...] BitsReader: Read bits from given ByteArray (1) [...]
Hi
Thanks for sharing this class as i was in really need of the same. I am writing a SWF reader in AIR and tried to use this class. However i am facing two errors on following lines while compiling
LINE 91:::
# result ^= (byte> (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH) ;
LINE 101:::
# result (BYTE_LEGNTH-leftBitsLength);
Can you please suggest what are the issues in these lines or what is the correct code
Sorry , there is something wrong with the codes in this article.
LINE 91:::
# result ^= (byte> (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH) ;
it should be :
result ^= (byte<>> (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH) ;
LINE 101:::
# result (BYTE_LEGNTH-leftBitsLength);
it should be :
result ^= byte>>(BYTE_LEGNTH-leftBitsLength);
Hi
Thanks for the fix and project download.
[...] 在BitsReader: Read bits from given ByteArray中专门介绍过针对SWF的Byte读去操作,Flex/Air本身其实支持png, gif, jpg,swf 格式的载入,不过却不支持BMP。这个其实是相当奇怪的,不过既然这样设计,那也没办法。只能自己写代码来解决BMP载入的问题了。好在Flex cookbook上已经提供了现成的代码并且有相关的说明,有需要的直接去取来用吧。下面是地址: [...]
[...] BitsReader: Read bits from given ByteArray (6) [...]
You want this
http://www.senocular.com/flash/actionscript/?file=ActionScript_3.0/com/senocular/utils/SWFReader.as