BitsReader: Read bits from given ByteArray

System-Binary 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.

Search-256x256 Demo | DownloadDownload Full Project

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 :) .

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • Reddit
  • Technorati
  • StumbleUpon
  • Twitter
RSS Enjoy this Post? Subscribe to Ntt.cc

RSS Feed   RSS Feed     Email Feed  Email Feed Follow us Follow us
You can leave a response, or trackback from your own site.

8 Responses to “BitsReader: Read bits from given ByteArray”

  1. 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…

  2. Yogesh Puri says:

    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

  3. Ntt.cc says:

    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);

  4. Yogesh Puri says:

    Hi

    Thanks for the fix and project download.

  5. [...] 在BitsReader: Read bits from given ByteArray中专门介绍过针对SWF的Byte读去操作,Flex/Air本身其实支持png, gif, jpg,swf 格式的载入,不过却不支持BMP。这个其实是相当奇怪的,不过既然这样设计,那也没办法。只能自己写代码来解决BMP载入的问题了。好在Flex cookbook上已经提供了现成的代码并且有相关的说明,有需要的直接去取来用吧。下面是地址: [...]

Leave a Reply