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:

  1. RECT
  2. Field Type Comment
  3. Nbits UB[5] Bits in each rect value field
  4. Xmin SB[Nbits] x minimum position for rect
  5. Xmax SB[Nbits] x maximum position for rect
  6. Ymin SB[Nbits] y minimum position for rect
  7. 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

Download: BitsReader.as
  1. package com.edison.utils
  2. {
  3.     import flash.utils.ByteArray;
  4.    
  5.     public class BitsReader
  6.     {   
  7.         private var _source:ByteArray;
  8.        
  9.         private var maxBitsLength:uint;
  10.        
  11.         private const BYTE_LEGNTH:uint = 8;
  12.        
  13.         private const NUMBER_LENGTH:uint = 53;
  14.        
  15.         private const INT_LENGTH:uint = 32;
  16.        
  17.         public function get source():ByteArray
  18.         {
  19.             return _source;
  20.         }    
  21.        
  22.         private var _position:uint = 0;
  23.        
  24.         public function get position():uint       
  25.         {
  26.             return _position;
  27.         }
  28.        
  29.         public function set position(value:uint):void
  30.         {
  31.             if(value > maxBitsLength)
  32.             {
  33.                 _position = maxBitsLength;
  34.             }
  35.             else
  36.             {
  37.                 _position = value;
  38.             }
  39.         }
  40.        
  41.         public function BitsReader(source:ByteArray)
  42.         {
  43.             maxBitsLength = source.length*BYTE_LEGNTH;
  44.             _source = source;
  45.         }
  46.        
  47.         public function read(length:uint):Number
  48.         {
  49.             //make sure the length of the return value is less or equal than the length of Number;
  50.             if(length> NUMBER_LENGTH)
  51.             {
  52.                 length = NUMBER_LENGTH;
  53.             }
  54.            
  55.             //make sure the length of the return value if less or equal the amount of all the bits.
  56.             if(length>maxBitsLength)
  57.             {
  58.                 length = maxBitsLength;
  59.             }
  60.            
  61.             //if there is not enought bits to return, return all the left.
  62.             if(length>maxBitsLength - position)
  63.             {
  64.                 length = maxBitsLength - position;
  65.             }
  66.                    
  67.             var result:Number = 0;
  68.            
  69.             var byteLength:uint = (position+length)/BYTE_LEGNTH;
  70.            
  71.             var leftBitsLength:uint = (position+length)%BYTE_LEGNTH;           
  72.            
  73.             var startByteIndex:uint = 0;
  74.             var extractFromFirstByte:Boolean = false;
  75.                        
  76.             if(position!=0)
  77.             {
  78.                 startByteIndex = Math.ceil(position/BYTE_LEGNTH)-1;
  79.                 extractFromFirstByte = true;
  80.             }
  81.             source.position = startByteIndex;
  82.            
  83.             var byte:uint = 0;
  84.             for(var i:uint = startByteIndex ;i<byteLength;i++)
  85.             {
  86.                 result <<= BYTE_LEGNTH;
  87.                 byte = source.readUnsignedByte();
  88.                
  89.                 if(extractFromFirstByte)
  90.                 {                   
  91.                     result ^= (byte<< (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH)) >>> (position%BYTE_LEGNTH+INT_LENGTH-BYTE_LEGNTH) ;
  92.                     position += (BYTE_LEGNTH - position%BYTE_LEGNTH);
  93.                     extractFromFirstByte = false;
  94.                 }
  95.                 else
  96.                 {                   
  97.                     result ^= byte;
  98.                     position += BYTE_LEGNTH;
  99.                 }               
  100.             }           
  101.             result <<= leftBitsLength;
  102.             byte = source.readUnsignedByte();
  103.            
  104.             result ^= byte>>(BYTE_LEGNTH-leftBitsLength);
  105.            
  106.             position += leftBitsLength;
  107.                        
  108.             return result;
  109.         }
  110.        
  111.     }
  112. }

This is a sample of BitsReader, quite easy.

  1. var rect:ByteArray = new ByteArray();
  2. uncompressedData.readBytes(rect,0,9);
  3.  
  4. var bits:BitsReader = new BitsReader(rect);
  5. bits.read(5);
  6. bits.read(15);
  7. trace(file width: “,bits.read(15)/20,”pixel”);
  8. bits.read(15);
  9. 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
You can leave a response, or trackback from your own site.

7 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