BitReader.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /* globals BitReader:true */
  2. /* exported BitReader */
  3. /**
  4. * Reads unsigned integers encoded in a variable amount of bits from the buffer.
  5. * Bits are aligned into 32bit unsigned integers.
  6. * for example, given 3 integers:
  7. * x: 123 encoded in 11 bits, binary: 00001111011
  8. * y: 7945 encoded in 17 bits, binary: 00001111100001001
  9. * z: 12 encoded in 6 bits, binary: 001100
  10. *
  11. * | --- 32 bits --- || --- 32 bits --- |
  12. * |................................||................................|
  13. * |00001111011000011111000010010011||00
  14. * | x || y || z |
  15. *
  16. * z does not fit fully into the first 32 bit integer.
  17. * The first 4 bits of z are stored at the end of the first 32 bit integer
  18. * and the remaining 2 bits at the next 32 bit integer.
  19. *
  20. */
  21. BitReader = function (buf) {
  22. let buffer = new Uint32Array(buf);
  23. let bitOffset = 0;
  24. this.read = function (bits) {
  25. let result;
  26. // TODO val & leftGap seem to be duplicate code? Move out of if-block
  27. if ((bitOffset % 32) + bits <= 32) {
  28. let val = buffer[Math.floor(bitOffset / 32)];
  29. let leftGap = bitOffset % 32;
  30. let rightGap = 32 - (leftGap + bits);
  31. result = (val << leftGap) >>> (leftGap + rightGap);
  32. } else {
  33. let val = buffer[Math.floor(bitOffset / 32)];
  34. let leftGap = bitOffset % 32;
  35. let rightGap = (leftGap + bits) - 32;
  36. result = (val << leftGap) >>> (leftGap - rightGap);
  37. val = buffer[Math.floor(bitOffset / 32) + 1];
  38. result = result | val >>> (32 - rightGap);
  39. }
  40. bitOffset += bits;
  41. return result;
  42. };
  43. };