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