PageRenderTime 103ms CodeModel.GetById 40ms app.highlight 13ms RepoModel.GetById 47ms app.codeStats 0ms

/Play/bits.js

http://github.com/mbebenita/Broadway
JavaScript | 218 lines | 146 code | 23 blank | 49 comment | 21 complexity | e1fd83f495cf2ea6006f298160542546 MD5 | raw file
  1'use strict';
  2
  3var trace = false;
  4
  5/**
  6 * Represents a bit stream view over a RBSP buffer. 
  7 */
  8var Bitstream = (function () {
  9    /**
 10     * @param {Uint8Array} ptr A pointer to a buffer underlying this bitstream.
 11     */
 12    function constructor(ptr) {
 13        this.incnt = 0;
 14        this.incnt_next = 0;
 15        this.bitcnt = 0;
 16        this.curr_word = this.next_word = 0;
 17        this.read_pos = 0;
 18        this.buffer = ptr;
 19        if (trace) printArray(ptr);
 20    }
 21    
 22    constructor.prototype.flush = function (n) {
 23        this.bitcnt += n;
 24        this.incnt -= n;
 25        this.curr_word <<= n;
 26    };
 27    
 28    /**
 29     * Reads up to 32 bits.
 30     */
 31    constructor.prototype.fill = function () {
 32        if (trace) println("Before Fill: " + this.toString());
 33        var buffer = this.buffer;
 34        var num_bits;
 35
 36        this.curr_word |= (this.next_word >>> this.incnt);   // this.incnt cannot be 32
 37        this.next_word <<= (31 - this.incnt);
 38        this.next_word <<= 1;
 39        num_bits = this.incnt_next + this.incnt;
 40        if (num_bits >= 32) {
 41            this.incnt_next -= (32 - this.incnt);
 42            this.incnt = 32;
 43        }
 44
 45        var pos = this.read_pos;
 46        
 47        if (this.read_pos > buffer.length - 4) {
 48            if (buffer.length <= this.read_pos) {
 49                this.incnt = num_bits;
 50                this.incnt_next = 0;
 51            }
 52            this.next_word = 0;
 53            for (var i = 0; i < buffer.length - this.read_pos; i++) {
 54                this.next_word |= (buffer[pos + i] << ((3 - i) << 3));
 55            }
 56            this.read_pos = buffer.length;
 57            this.curr_word |= (this.next_word >> num_bits);
 58            this.next_word <<= (31 - num_bits);
 59            this.next_word <<= 1;
 60            num_bits = i << 3;
 61            this.incnt += this.incnt_next;
 62            this.incnt_next = num_bits - (32 - this.incnt);
 63            if (this.incnt_next < 0) {
 64                this.incnt +=  num_bits;
 65                this.incnt_next = 0;
 66            } else {
 67                this.incnt = 32;
 68            }
 69            if (trace) println("After Fill: " + this.toString());
 70            return;
 71        }
 72        
 73        this.next_word = (buffer[pos] << 24 | (buffer[pos + 1] << 16) | (buffer[pos + 2] << 8) | buffer[pos + 3]);
 74        this.read_pos += 4;
 75
 76        this.curr_word |= (this.next_word >>> num_bits); // this is safe
 77        this.next_word <<= (31 - num_bits);
 78        this.next_word <<= 1;
 79        this.incnt_next += this.incnt;
 80        this.incnt = 32;
 81        if (trace) println("After Fill: " + this.toString());
 82    };
 83    
 84    /*
 85     * Reads up to one machine word.
 86     */
 87    constructor.prototype.readBits = function (n) {
 88        if (this.incnt < n) {
 89            this.fill();
 90        }
 91        var bits = this.curr_word >>> (32 - n);
 92        this.flush(n);
 93        return bits;
 94    };
 95    
 96    /*
 97     * Reads up to one machine word but does not advance.
 98     */
 99    constructor.prototype.peekBits = function (n) {
100        if (this.incnt < n) {
101            this.fill();
102        }
103        return this.curr_word >>> (32 - n);
104    };
105    
106    /*
107     * Reads a single bit.
108     */
109    constructor.prototype.readBit = function () {
110        if (this.incnt < 1) {
111            this.fill();
112        }
113        var bit = this.curr_word >>> 31;
114        this.flush(1);
115        return bit;
116    };
117    
118    /*
119     * Exponential-Golomb Coding:
120     * See algorithm in Section 9.1, Table 9-1, Table 9-2.
121     * 
122     *  Pattern    Code
123     *  
124     *     1          0
125     *    01X       1,2
126     *   001XX      3,6
127     *  0001XXX    7,14
128     * 00001XXXX  15,30
129     * .........  .....
130     * 
131     * Code = 2 ^ (z) - 1 + readBits(z), where n is the number of leading zeros up until the first 1 bit, and
132     * readBits(z) are the z bits following the first bit 1.
133     * 
134     */
135    
136
137    /**
138     * Unsigned Exponential-Golomb Coding for 16 bit values.
139     */ 
140    constructor.prototype.uev = function () {
141        var temp = this.peekBits(16);
142        // if (trace) println("uev bits: " + getNumberInfo(temp));
143        var leading_zeros = countLeadingZeros16(temp | 0x1);
144        // if (trace) println("uev lzs: " + leading_zeros);
145        if (leading_zeros < 8) {
146            var code = (temp >>> (15 - (leading_zeros << 1))) - 1;
147            this.flush((leading_zeros << 1) + 1);
148            return code;
149        }
150        return this.readBits((leading_zeros << 1) + 1) - 1;
151    };
152    
153    /**
154     *  Signed Exponential-Golomb Coding for 16 bit values. 
155     */
156    constructor.prototype.sev = function () {
157        var temp = this.peekBits(16);
158        var leading_zeros = countLeadingZeros16(temp | 0x1);
159        if (leading_zeros < 8) {
160            temp >>>= (15 - (leading_zeros << 1));
161            this.flush((leading_zeros << 1) + 1);
162        } else {
163            temp = this.readBits((leading_zeros << 1) + 1);
164        }
165        var ret = temp >>> 1;
166        if (temp & 0x01) {
167            ret = -ret;
168        }
169        return ret;
170    };
171    
172    /**
173     * Read Exponential-Golomb 32 bit values with range from -2^31 to 2^31-1. 
174     */
175    constructor.prototype.readEBBits32 = function () {
176        var bit = this.readBit();
177        var leading_zeros = 0;
178        while(!bit) {
179            leading_zeros += 1;
180            bit = this.readBit();
181        }
182        
183        if (leading_zeros > 0) {
184            return this.readBits(leading_zeros);
185        }
186        return 0;
187    };
188
189    /*
190     * Signed Exponential-Golomb Coding for 32 bit values. 
191     */
192    constructor.prototype.sev32 = function () {
193        var bit = this.readBit();
194        var leading_zeros = 0;
195        while(!bit) {
196            leading_zeros += 1;
197            bit = this.readBit();
198        }
199        
200        var bits = 0;
201        if (leading_zeros > 0) {
202            bits = this.readBits(leading_zeros);
203        }
204        
205        var code = (1 << leading_zeros) - 1 + bits;
206        var value = (code + 1) / 2;
207
208        if ((code & 0x01) == 0) {
209            value = -value;
210        }
211        return value;
212    };
213
214    constructor.prototype.toString = function () {
215        return getProperties(this, true);
216    };
217    return constructor;
218})();