arithmetic_decoder.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /* Copyright 2012 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. /* eslint no-var: error */
  16. // Table C-2
  17. const QeTable = [
  18. { qe: 0x5601, nmps: 1, nlps: 1, switchFlag: 1 },
  19. { qe: 0x3401, nmps: 2, nlps: 6, switchFlag: 0 },
  20. { qe: 0x1801, nmps: 3, nlps: 9, switchFlag: 0 },
  21. { qe: 0x0ac1, nmps: 4, nlps: 12, switchFlag: 0 },
  22. { qe: 0x0521, nmps: 5, nlps: 29, switchFlag: 0 },
  23. { qe: 0x0221, nmps: 38, nlps: 33, switchFlag: 0 },
  24. { qe: 0x5601, nmps: 7, nlps: 6, switchFlag: 1 },
  25. { qe: 0x5401, nmps: 8, nlps: 14, switchFlag: 0 },
  26. { qe: 0x4801, nmps: 9, nlps: 14, switchFlag: 0 },
  27. { qe: 0x3801, nmps: 10, nlps: 14, switchFlag: 0 },
  28. { qe: 0x3001, nmps: 11, nlps: 17, switchFlag: 0 },
  29. { qe: 0x2401, nmps: 12, nlps: 18, switchFlag: 0 },
  30. { qe: 0x1c01, nmps: 13, nlps: 20, switchFlag: 0 },
  31. { qe: 0x1601, nmps: 29, nlps: 21, switchFlag: 0 },
  32. { qe: 0x5601, nmps: 15, nlps: 14, switchFlag: 1 },
  33. { qe: 0x5401, nmps: 16, nlps: 14, switchFlag: 0 },
  34. { qe: 0x5101, nmps: 17, nlps: 15, switchFlag: 0 },
  35. { qe: 0x4801, nmps: 18, nlps: 16, switchFlag: 0 },
  36. { qe: 0x3801, nmps: 19, nlps: 17, switchFlag: 0 },
  37. { qe: 0x3401, nmps: 20, nlps: 18, switchFlag: 0 },
  38. { qe: 0x3001, nmps: 21, nlps: 19, switchFlag: 0 },
  39. { qe: 0x2801, nmps: 22, nlps: 19, switchFlag: 0 },
  40. { qe: 0x2401, nmps: 23, nlps: 20, switchFlag: 0 },
  41. { qe: 0x2201, nmps: 24, nlps: 21, switchFlag: 0 },
  42. { qe: 0x1c01, nmps: 25, nlps: 22, switchFlag: 0 },
  43. { qe: 0x1801, nmps: 26, nlps: 23, switchFlag: 0 },
  44. { qe: 0x1601, nmps: 27, nlps: 24, switchFlag: 0 },
  45. { qe: 0x1401, nmps: 28, nlps: 25, switchFlag: 0 },
  46. { qe: 0x1201, nmps: 29, nlps: 26, switchFlag: 0 },
  47. { qe: 0x1101, nmps: 30, nlps: 27, switchFlag: 0 },
  48. { qe: 0x0ac1, nmps: 31, nlps: 28, switchFlag: 0 },
  49. { qe: 0x09c1, nmps: 32, nlps: 29, switchFlag: 0 },
  50. { qe: 0x08a1, nmps: 33, nlps: 30, switchFlag: 0 },
  51. { qe: 0x0521, nmps: 34, nlps: 31, switchFlag: 0 },
  52. { qe: 0x0441, nmps: 35, nlps: 32, switchFlag: 0 },
  53. { qe: 0x02a1, nmps: 36, nlps: 33, switchFlag: 0 },
  54. { qe: 0x0221, nmps: 37, nlps: 34, switchFlag: 0 },
  55. { qe: 0x0141, nmps: 38, nlps: 35, switchFlag: 0 },
  56. { qe: 0x0111, nmps: 39, nlps: 36, switchFlag: 0 },
  57. { qe: 0x0085, nmps: 40, nlps: 37, switchFlag: 0 },
  58. { qe: 0x0049, nmps: 41, nlps: 38, switchFlag: 0 },
  59. { qe: 0x0025, nmps: 42, nlps: 39, switchFlag: 0 },
  60. { qe: 0x0015, nmps: 43, nlps: 40, switchFlag: 0 },
  61. { qe: 0x0009, nmps: 44, nlps: 41, switchFlag: 0 },
  62. { qe: 0x0005, nmps: 45, nlps: 42, switchFlag: 0 },
  63. { qe: 0x0001, nmps: 45, nlps: 43, switchFlag: 0 },
  64. { qe: 0x5601, nmps: 46, nlps: 46, switchFlag: 0 },
  65. ];
  66. /**
  67. * This class implements the QM Coder decoding as defined in
  68. * JPEG 2000 Part I Final Committee Draft Version 1.0
  69. * Annex C.3 Arithmetic decoding procedure
  70. * available at http://www.jpeg.org/public/fcd15444-1.pdf
  71. *
  72. * The arithmetic decoder is used in conjunction with context models to decode
  73. * JPEG2000 and JBIG2 streams.
  74. */
  75. class ArithmeticDecoder {
  76. // C.3.5 Initialisation of the decoder (INITDEC)
  77. constructor(data, start, end) {
  78. this.data = data;
  79. this.bp = start;
  80. this.dataEnd = end;
  81. this.chigh = data[start];
  82. this.clow = 0;
  83. this.byteIn();
  84. this.chigh = ((this.chigh << 7) & 0xffff) | ((this.clow >> 9) & 0x7f);
  85. this.clow = (this.clow << 7) & 0xffff;
  86. this.ct -= 7;
  87. this.a = 0x8000;
  88. }
  89. // C.3.4 Compressed data input (BYTEIN)
  90. byteIn() {
  91. const data = this.data;
  92. let bp = this.bp;
  93. if (data[bp] === 0xff) {
  94. if (data[bp + 1] > 0x8f) {
  95. this.clow += 0xff00;
  96. this.ct = 8;
  97. } else {
  98. bp++;
  99. this.clow += data[bp] << 9;
  100. this.ct = 7;
  101. this.bp = bp;
  102. }
  103. } else {
  104. bp++;
  105. this.clow += bp < this.dataEnd ? data[bp] << 8 : 0xff00;
  106. this.ct = 8;
  107. this.bp = bp;
  108. }
  109. if (this.clow > 0xffff) {
  110. this.chigh += this.clow >> 16;
  111. this.clow &= 0xffff;
  112. }
  113. }
  114. // C.3.2 Decoding a decision (DECODE)
  115. readBit(contexts, pos) {
  116. // Contexts are packed into 1 byte:
  117. // highest 7 bits carry cx.index, lowest bit carries cx.mps
  118. let cx_index = contexts[pos] >> 1,
  119. cx_mps = contexts[pos] & 1;
  120. const qeTableIcx = QeTable[cx_index];
  121. const qeIcx = qeTableIcx.qe;
  122. let d;
  123. let a = this.a - qeIcx;
  124. if (this.chigh < qeIcx) {
  125. // exchangeLps
  126. if (a < qeIcx) {
  127. a = qeIcx;
  128. d = cx_mps;
  129. cx_index = qeTableIcx.nmps;
  130. } else {
  131. a = qeIcx;
  132. d = 1 ^ cx_mps;
  133. if (qeTableIcx.switchFlag === 1) {
  134. cx_mps = d;
  135. }
  136. cx_index = qeTableIcx.nlps;
  137. }
  138. } else {
  139. this.chigh -= qeIcx;
  140. if ((a & 0x8000) !== 0) {
  141. this.a = a;
  142. return cx_mps;
  143. }
  144. // exchangeMps
  145. if (a < qeIcx) {
  146. d = 1 ^ cx_mps;
  147. if (qeTableIcx.switchFlag === 1) {
  148. cx_mps = d;
  149. }
  150. cx_index = qeTableIcx.nlps;
  151. } else {
  152. d = cx_mps;
  153. cx_index = qeTableIcx.nmps;
  154. }
  155. }
  156. // C.3.3 renormD;
  157. do {
  158. if (this.ct === 0) {
  159. this.byteIn();
  160. }
  161. a <<= 1;
  162. this.chigh = ((this.chigh << 1) & 0xffff) | ((this.clow >> 15) & 1);
  163. this.clow = (this.clow << 1) & 0xffff;
  164. this.ct--;
  165. } while ((a & 0x8000) === 0);
  166. this.a = a;
  167. contexts[pos] = (cx_index << 1) | cx_mps;
  168. return d;
  169. }
  170. }
  171. export { ArithmeticDecoder };