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) [...]