ccitt.js 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  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. /* Copyright 1996-2003 Glyph & Cog, LLC
  16. *
  17. * The CCITT stream implementation contained in this file is a JavaScript port
  18. * of XPDF's implementation, made available under the Apache 2.0 open source
  19. * license.
  20. */
  21. /**
  22. * @typedef {Object} CCITTFaxDecoderSource
  23. * @property {function} next - Method that return one byte of data for decoding,
  24. * or -1 when EOF is reached.
  25. */
  26. import { info } from "./util.js";
  27. const CCITTFaxDecoder = (function CCITTFaxDecoder() {
  28. const ccittEOL = -2;
  29. const ccittEOF = -1;
  30. const twoDimPass = 0;
  31. const twoDimHoriz = 1;
  32. const twoDimVert0 = 2;
  33. const twoDimVertR1 = 3;
  34. const twoDimVertL1 = 4;
  35. const twoDimVertR2 = 5;
  36. const twoDimVertL2 = 6;
  37. const twoDimVertR3 = 7;
  38. const twoDimVertL3 = 8;
  39. // prettier-ignore
  40. const twoDimTable = [
  41. [-1, -1], [-1, -1], // 000000x
  42. [7, twoDimVertL3], // 0000010
  43. [7, twoDimVertR3], // 0000011
  44. [6, twoDimVertL2], [6, twoDimVertL2], // 000010x
  45. [6, twoDimVertR2], [6, twoDimVertR2], // 000011x
  46. [4, twoDimPass], [4, twoDimPass], // 0001xxx
  47. [4, twoDimPass], [4, twoDimPass],
  48. [4, twoDimPass], [4, twoDimPass],
  49. [4, twoDimPass], [4, twoDimPass],
  50. [3, twoDimHoriz], [3, twoDimHoriz], // 001xxxx
  51. [3, twoDimHoriz], [3, twoDimHoriz],
  52. [3, twoDimHoriz], [3, twoDimHoriz],
  53. [3, twoDimHoriz], [3, twoDimHoriz],
  54. [3, twoDimHoriz], [3, twoDimHoriz],
  55. [3, twoDimHoriz], [3, twoDimHoriz],
  56. [3, twoDimHoriz], [3, twoDimHoriz],
  57. [3, twoDimHoriz], [3, twoDimHoriz],
  58. [3, twoDimVertL1], [3, twoDimVertL1], // 010xxxx
  59. [3, twoDimVertL1], [3, twoDimVertL1],
  60. [3, twoDimVertL1], [3, twoDimVertL1],
  61. [3, twoDimVertL1], [3, twoDimVertL1],
  62. [3, twoDimVertL1], [3, twoDimVertL1],
  63. [3, twoDimVertL1], [3, twoDimVertL1],
  64. [3, twoDimVertL1], [3, twoDimVertL1],
  65. [3, twoDimVertL1], [3, twoDimVertL1],
  66. [3, twoDimVertR1], [3, twoDimVertR1], // 011xxxx
  67. [3, twoDimVertR1], [3, twoDimVertR1],
  68. [3, twoDimVertR1], [3, twoDimVertR1],
  69. [3, twoDimVertR1], [3, twoDimVertR1],
  70. [3, twoDimVertR1], [3, twoDimVertR1],
  71. [3, twoDimVertR1], [3, twoDimVertR1],
  72. [3, twoDimVertR1], [3, twoDimVertR1],
  73. [3, twoDimVertR1], [3, twoDimVertR1],
  74. [1, twoDimVert0], [1, twoDimVert0], // 1xxxxxx
  75. [1, twoDimVert0], [1, twoDimVert0],
  76. [1, twoDimVert0], [1, twoDimVert0],
  77. [1, twoDimVert0], [1, twoDimVert0],
  78. [1, twoDimVert0], [1, twoDimVert0],
  79. [1, twoDimVert0], [1, twoDimVert0],
  80. [1, twoDimVert0], [1, twoDimVert0],
  81. [1, twoDimVert0], [1, twoDimVert0],
  82. [1, twoDimVert0], [1, twoDimVert0],
  83. [1, twoDimVert0], [1, twoDimVert0],
  84. [1, twoDimVert0], [1, twoDimVert0],
  85. [1, twoDimVert0], [1, twoDimVert0],
  86. [1, twoDimVert0], [1, twoDimVert0],
  87. [1, twoDimVert0], [1, twoDimVert0],
  88. [1, twoDimVert0], [1, twoDimVert0],
  89. [1, twoDimVert0], [1, twoDimVert0],
  90. [1, twoDimVert0], [1, twoDimVert0],
  91. [1, twoDimVert0], [1, twoDimVert0],
  92. [1, twoDimVert0], [1, twoDimVert0],
  93. [1, twoDimVert0], [1, twoDimVert0],
  94. [1, twoDimVert0], [1, twoDimVert0],
  95. [1, twoDimVert0], [1, twoDimVert0],
  96. [1, twoDimVert0], [1, twoDimVert0],
  97. [1, twoDimVert0], [1, twoDimVert0],
  98. [1, twoDimVert0], [1, twoDimVert0],
  99. [1, twoDimVert0], [1, twoDimVert0],
  100. [1, twoDimVert0], [1, twoDimVert0],
  101. [1, twoDimVert0], [1, twoDimVert0],
  102. [1, twoDimVert0], [1, twoDimVert0],
  103. [1, twoDimVert0], [1, twoDimVert0],
  104. [1, twoDimVert0], [1, twoDimVert0],
  105. [1, twoDimVert0], [1, twoDimVert0]
  106. ];
  107. // prettier-ignore
  108. const whiteTable1 = [
  109. [-1, -1], // 00000
  110. [12, ccittEOL], // 00001
  111. [-1, -1], [-1, -1], // 0001x
  112. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 001xx
  113. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 010xx
  114. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 011xx
  115. [11, 1792], [11, 1792], // 1000x
  116. [12, 1984], // 10010
  117. [12, 2048], // 10011
  118. [12, 2112], // 10100
  119. [12, 2176], // 10101
  120. [12, 2240], // 10110
  121. [12, 2304], // 10111
  122. [11, 1856], [11, 1856], // 1100x
  123. [11, 1920], [11, 1920], // 1101x
  124. [12, 2368], // 11100
  125. [12, 2432], // 11101
  126. [12, 2496], // 11110
  127. [12, 2560] // 11111
  128. ];
  129. // prettier-ignore
  130. const whiteTable2 = [
  131. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 0000000xx
  132. [8, 29], [8, 29], // 00000010x
  133. [8, 30], [8, 30], // 00000011x
  134. [8, 45], [8, 45], // 00000100x
  135. [8, 46], [8, 46], // 00000101x
  136. [7, 22], [7, 22], [7, 22], [7, 22], // 0000011xx
  137. [7, 23], [7, 23], [7, 23], [7, 23], // 0000100xx
  138. [8, 47], [8, 47], // 00001010x
  139. [8, 48], [8, 48], // 00001011x
  140. [6, 13], [6, 13], [6, 13], [6, 13], // 000011xxx
  141. [6, 13], [6, 13], [6, 13], [6, 13],
  142. [7, 20], [7, 20], [7, 20], [7, 20], // 0001000xx
  143. [8, 33], [8, 33], // 00010010x
  144. [8, 34], [8, 34], // 00010011x
  145. [8, 35], [8, 35], // 00010100x
  146. [8, 36], [8, 36], // 00010101x
  147. [8, 37], [8, 37], // 00010110x
  148. [8, 38], [8, 38], // 00010111x
  149. [7, 19], [7, 19], [7, 19], [7, 19], // 0001100xx
  150. [8, 31], [8, 31], // 00011010x
  151. [8, 32], [8, 32], // 00011011x
  152. [6, 1], [6, 1], [6, 1], [6, 1], // 000111xxx
  153. [6, 1], [6, 1], [6, 1], [6, 1],
  154. [6, 12], [6, 12], [6, 12], [6, 12], // 001000xxx
  155. [6, 12], [6, 12], [6, 12], [6, 12],
  156. [8, 53], [8, 53], // 00100100x
  157. [8, 54], [8, 54], // 00100101x
  158. [7, 26], [7, 26], [7, 26], [7, 26], // 0010011xx
  159. [8, 39], [8, 39], // 00101000x
  160. [8, 40], [8, 40], // 00101001x
  161. [8, 41], [8, 41], // 00101010x
  162. [8, 42], [8, 42], // 00101011x
  163. [8, 43], [8, 43], // 00101100x
  164. [8, 44], [8, 44], // 00101101x
  165. [7, 21], [7, 21], [7, 21], [7, 21], // 0010111xx
  166. [7, 28], [7, 28], [7, 28], [7, 28], // 0011000xx
  167. [8, 61], [8, 61], // 00110010x
  168. [8, 62], [8, 62], // 00110011x
  169. [8, 63], [8, 63], // 00110100x
  170. [8, 0], [8, 0], // 00110101x
  171. [8, 320], [8, 320], // 00110110x
  172. [8, 384], [8, 384], // 00110111x
  173. [5, 10], [5, 10], [5, 10], [5, 10], // 00111xxxx
  174. [5, 10], [5, 10], [5, 10], [5, 10],
  175. [5, 10], [5, 10], [5, 10], [5, 10],
  176. [5, 10], [5, 10], [5, 10], [5, 10],
  177. [5, 11], [5, 11], [5, 11], [5, 11], // 01000xxxx
  178. [5, 11], [5, 11], [5, 11], [5, 11],
  179. [5, 11], [5, 11], [5, 11], [5, 11],
  180. [5, 11], [5, 11], [5, 11], [5, 11],
  181. [7, 27], [7, 27], [7, 27], [7, 27], // 0100100xx
  182. [8, 59], [8, 59], // 01001010x
  183. [8, 60], [8, 60], // 01001011x
  184. [9, 1472], // 010011000
  185. [9, 1536], // 010011001
  186. [9, 1600], // 010011010
  187. [9, 1728], // 010011011
  188. [7, 18], [7, 18], [7, 18], [7, 18], // 0100111xx
  189. [7, 24], [7, 24], [7, 24], [7, 24], // 0101000xx
  190. [8, 49], [8, 49], // 01010010x
  191. [8, 50], [8, 50], // 01010011x
  192. [8, 51], [8, 51], // 01010100x
  193. [8, 52], [8, 52], // 01010101x
  194. [7, 25], [7, 25], [7, 25], [7, 25], // 0101011xx
  195. [8, 55], [8, 55], // 01011000x
  196. [8, 56], [8, 56], // 01011001x
  197. [8, 57], [8, 57], // 01011010x
  198. [8, 58], [8, 58], // 01011011x
  199. [6, 192], [6, 192], [6, 192], [6, 192], // 010111xxx
  200. [6, 192], [6, 192], [6, 192], [6, 192],
  201. [6, 1664], [6, 1664], [6, 1664], [6, 1664], // 011000xxx
  202. [6, 1664], [6, 1664], [6, 1664], [6, 1664],
  203. [8, 448], [8, 448], // 01100100x
  204. [8, 512], [8, 512], // 01100101x
  205. [9, 704], // 011001100
  206. [9, 768], // 011001101
  207. [8, 640], [8, 640], // 01100111x
  208. [8, 576], [8, 576], // 01101000x
  209. [9, 832], // 011010010
  210. [9, 896], // 011010011
  211. [9, 960], // 011010100
  212. [9, 1024], // 011010101
  213. [9, 1088], // 011010110
  214. [9, 1152], // 011010111
  215. [9, 1216], // 011011000
  216. [9, 1280], // 011011001
  217. [9, 1344], // 011011010
  218. [9, 1408], // 011011011
  219. [7, 256], [7, 256], [7, 256], [7, 256], // 0110111xx
  220. [4, 2], [4, 2], [4, 2], [4, 2], // 0111xxxxx
  221. [4, 2], [4, 2], [4, 2], [4, 2],
  222. [4, 2], [4, 2], [4, 2], [4, 2],
  223. [4, 2], [4, 2], [4, 2], [4, 2],
  224. [4, 2], [4, 2], [4, 2], [4, 2],
  225. [4, 2], [4, 2], [4, 2], [4, 2],
  226. [4, 2], [4, 2], [4, 2], [4, 2],
  227. [4, 2], [4, 2], [4, 2], [4, 2],
  228. [4, 3], [4, 3], [4, 3], [4, 3], // 1000xxxxx
  229. [4, 3], [4, 3], [4, 3], [4, 3],
  230. [4, 3], [4, 3], [4, 3], [4, 3],
  231. [4, 3], [4, 3], [4, 3], [4, 3],
  232. [4, 3], [4, 3], [4, 3], [4, 3],
  233. [4, 3], [4, 3], [4, 3], [4, 3],
  234. [4, 3], [4, 3], [4, 3], [4, 3],
  235. [4, 3], [4, 3], [4, 3], [4, 3],
  236. [5, 128], [5, 128], [5, 128], [5, 128], // 10010xxxx
  237. [5, 128], [5, 128], [5, 128], [5, 128],
  238. [5, 128], [5, 128], [5, 128], [5, 128],
  239. [5, 128], [5, 128], [5, 128], [5, 128],
  240. [5, 8], [5, 8], [5, 8], [5, 8], // 10011xxxx
  241. [5, 8], [5, 8], [5, 8], [5, 8],
  242. [5, 8], [5, 8], [5, 8], [5, 8],
  243. [5, 8], [5, 8], [5, 8], [5, 8],
  244. [5, 9], [5, 9], [5, 9], [5, 9], // 10100xxxx
  245. [5, 9], [5, 9], [5, 9], [5, 9],
  246. [5, 9], [5, 9], [5, 9], [5, 9],
  247. [5, 9], [5, 9], [5, 9], [5, 9],
  248. [6, 16], [6, 16], [6, 16], [6, 16], // 101010xxx
  249. [6, 16], [6, 16], [6, 16], [6, 16],
  250. [6, 17], [6, 17], [6, 17], [6, 17], // 101011xxx
  251. [6, 17], [6, 17], [6, 17], [6, 17],
  252. [4, 4], [4, 4], [4, 4], [4, 4], // 1011xxxxx
  253. [4, 4], [4, 4], [4, 4], [4, 4],
  254. [4, 4], [4, 4], [4, 4], [4, 4],
  255. [4, 4], [4, 4], [4, 4], [4, 4],
  256. [4, 4], [4, 4], [4, 4], [4, 4],
  257. [4, 4], [4, 4], [4, 4], [4, 4],
  258. [4, 4], [4, 4], [4, 4], [4, 4],
  259. [4, 4], [4, 4], [4, 4], [4, 4],
  260. [4, 5], [4, 5], [4, 5], [4, 5], // 1100xxxxx
  261. [4, 5], [4, 5], [4, 5], [4, 5],
  262. [4, 5], [4, 5], [4, 5], [4, 5],
  263. [4, 5], [4, 5], [4, 5], [4, 5],
  264. [4, 5], [4, 5], [4, 5], [4, 5],
  265. [4, 5], [4, 5], [4, 5], [4, 5],
  266. [4, 5], [4, 5], [4, 5], [4, 5],
  267. [4, 5], [4, 5], [4, 5], [4, 5],
  268. [6, 14], [6, 14], [6, 14], [6, 14], // 110100xxx
  269. [6, 14], [6, 14], [6, 14], [6, 14],
  270. [6, 15], [6, 15], [6, 15], [6, 15], // 110101xxx
  271. [6, 15], [6, 15], [6, 15], [6, 15],
  272. [5, 64], [5, 64], [5, 64], [5, 64], // 11011xxxx
  273. [5, 64], [5, 64], [5, 64], [5, 64],
  274. [5, 64], [5, 64], [5, 64], [5, 64],
  275. [5, 64], [5, 64], [5, 64], [5, 64],
  276. [4, 6], [4, 6], [4, 6], [4, 6], // 1110xxxxx
  277. [4, 6], [4, 6], [4, 6], [4, 6],
  278. [4, 6], [4, 6], [4, 6], [4, 6],
  279. [4, 6], [4, 6], [4, 6], [4, 6],
  280. [4, 6], [4, 6], [4, 6], [4, 6],
  281. [4, 6], [4, 6], [4, 6], [4, 6],
  282. [4, 6], [4, 6], [4, 6], [4, 6],
  283. [4, 6], [4, 6], [4, 6], [4, 6],
  284. [4, 7], [4, 7], [4, 7], [4, 7], // 1111xxxxx
  285. [4, 7], [4, 7], [4, 7], [4, 7],
  286. [4, 7], [4, 7], [4, 7], [4, 7],
  287. [4, 7], [4, 7], [4, 7], [4, 7],
  288. [4, 7], [4, 7], [4, 7], [4, 7],
  289. [4, 7], [4, 7], [4, 7], [4, 7],
  290. [4, 7], [4, 7], [4, 7], [4, 7],
  291. [4, 7], [4, 7], [4, 7], [4, 7]
  292. ];
  293. // prettier-ignore
  294. const blackTable1 = [
  295. [-1, -1], [-1, -1], // 000000000000x
  296. [12, ccittEOL], [12, ccittEOL], // 000000000001x
  297. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000001xx
  298. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000010xx
  299. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000011xx
  300. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000100xx
  301. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000101xx
  302. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000110xx
  303. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000111xx
  304. [11, 1792], [11, 1792], [11, 1792], [11, 1792], // 00000001000xx
  305. [12, 1984], [12, 1984], // 000000010010x
  306. [12, 2048], [12, 2048], // 000000010011x
  307. [12, 2112], [12, 2112], // 000000010100x
  308. [12, 2176], [12, 2176], // 000000010101x
  309. [12, 2240], [12, 2240], // 000000010110x
  310. [12, 2304], [12, 2304], // 000000010111x
  311. [11, 1856], [11, 1856], [11, 1856], [11, 1856], // 00000001100xx
  312. [11, 1920], [11, 1920], [11, 1920], [11, 1920], // 00000001101xx
  313. [12, 2368], [12, 2368], // 000000011100x
  314. [12, 2432], [12, 2432], // 000000011101x
  315. [12, 2496], [12, 2496], // 000000011110x
  316. [12, 2560], [12, 2560], // 000000011111x
  317. [10, 18], [10, 18], [10, 18], [10, 18], // 0000001000xxx
  318. [10, 18], [10, 18], [10, 18], [10, 18],
  319. [12, 52], [12, 52], // 000000100100x
  320. [13, 640], // 0000001001010
  321. [13, 704], // 0000001001011
  322. [13, 768], // 0000001001100
  323. [13, 832], // 0000001001101
  324. [12, 55], [12, 55], // 000000100111x
  325. [12, 56], [12, 56], // 000000101000x
  326. [13, 1280], // 0000001010010
  327. [13, 1344], // 0000001010011
  328. [13, 1408], // 0000001010100
  329. [13, 1472], // 0000001010101
  330. [12, 59], [12, 59], // 000000101011x
  331. [12, 60], [12, 60], // 000000101100x
  332. [13, 1536], // 0000001011010
  333. [13, 1600], // 0000001011011
  334. [11, 24], [11, 24], [11, 24], [11, 24], // 00000010111xx
  335. [11, 25], [11, 25], [11, 25], [11, 25], // 00000011000xx
  336. [13, 1664], // 0000001100100
  337. [13, 1728], // 0000001100101
  338. [12, 320], [12, 320], // 000000110011x
  339. [12, 384], [12, 384], // 000000110100x
  340. [12, 448], [12, 448], // 000000110101x
  341. [13, 512], // 0000001101100
  342. [13, 576], // 0000001101101
  343. [12, 53], [12, 53], // 000000110111x
  344. [12, 54], [12, 54], // 000000111000x
  345. [13, 896], // 0000001110010
  346. [13, 960], // 0000001110011
  347. [13, 1024], // 0000001110100
  348. [13, 1088], // 0000001110101
  349. [13, 1152], // 0000001110110
  350. [13, 1216], // 0000001110111
  351. [10, 64], [10, 64], [10, 64], [10, 64], // 0000001111xxx
  352. [10, 64], [10, 64], [10, 64], [10, 64]
  353. ];
  354. // prettier-ignore
  355. const blackTable2 = [
  356. [8, 13], [8, 13], [8, 13], [8, 13], // 00000100xxxx
  357. [8, 13], [8, 13], [8, 13], [8, 13],
  358. [8, 13], [8, 13], [8, 13], [8, 13],
  359. [8, 13], [8, 13], [8, 13], [8, 13],
  360. [11, 23], [11, 23], // 00000101000x
  361. [12, 50], // 000001010010
  362. [12, 51], // 000001010011
  363. [12, 44], // 000001010100
  364. [12, 45], // 000001010101
  365. [12, 46], // 000001010110
  366. [12, 47], // 000001010111
  367. [12, 57], // 000001011000
  368. [12, 58], // 000001011001
  369. [12, 61], // 000001011010
  370. [12, 256], // 000001011011
  371. [10, 16], [10, 16], [10, 16], [10, 16], // 0000010111xx
  372. [10, 17], [10, 17], [10, 17], [10, 17], // 0000011000xx
  373. [12, 48], // 000001100100
  374. [12, 49], // 000001100101
  375. [12, 62], // 000001100110
  376. [12, 63], // 000001100111
  377. [12, 30], // 000001101000
  378. [12, 31], // 000001101001
  379. [12, 32], // 000001101010
  380. [12, 33], // 000001101011
  381. [12, 40], // 000001101100
  382. [12, 41], // 000001101101
  383. [11, 22], [11, 22], // 00000110111x
  384. [8, 14], [8, 14], [8, 14], [8, 14], // 00000111xxxx
  385. [8, 14], [8, 14], [8, 14], [8, 14],
  386. [8, 14], [8, 14], [8, 14], [8, 14],
  387. [8, 14], [8, 14], [8, 14], [8, 14],
  388. [7, 10], [7, 10], [7, 10], [7, 10], // 0000100xxxxx
  389. [7, 10], [7, 10], [7, 10], [7, 10],
  390. [7, 10], [7, 10], [7, 10], [7, 10],
  391. [7, 10], [7, 10], [7, 10], [7, 10],
  392. [7, 10], [7, 10], [7, 10], [7, 10],
  393. [7, 10], [7, 10], [7, 10], [7, 10],
  394. [7, 10], [7, 10], [7, 10], [7, 10],
  395. [7, 10], [7, 10], [7, 10], [7, 10],
  396. [7, 11], [7, 11], [7, 11], [7, 11], // 0000101xxxxx
  397. [7, 11], [7, 11], [7, 11], [7, 11],
  398. [7, 11], [7, 11], [7, 11], [7, 11],
  399. [7, 11], [7, 11], [7, 11], [7, 11],
  400. [7, 11], [7, 11], [7, 11], [7, 11],
  401. [7, 11], [7, 11], [7, 11], [7, 11],
  402. [7, 11], [7, 11], [7, 11], [7, 11],
  403. [7, 11], [7, 11], [7, 11], [7, 11],
  404. [9, 15], [9, 15], [9, 15], [9, 15], // 000011000xxx
  405. [9, 15], [9, 15], [9, 15], [9, 15],
  406. [12, 128], // 000011001000
  407. [12, 192], // 000011001001
  408. [12, 26], // 000011001010
  409. [12, 27], // 000011001011
  410. [12, 28], // 000011001100
  411. [12, 29], // 000011001101
  412. [11, 19], [11, 19], // 00001100111x
  413. [11, 20], [11, 20], // 00001101000x
  414. [12, 34], // 000011010010
  415. [12, 35], // 000011010011
  416. [12, 36], // 000011010100
  417. [12, 37], // 000011010101
  418. [12, 38], // 000011010110
  419. [12, 39], // 000011010111
  420. [11, 21], [11, 21], // 00001101100x
  421. [12, 42], // 000011011010
  422. [12, 43], // 000011011011
  423. [10, 0], [10, 0], [10, 0], [10, 0], // 0000110111xx
  424. [7, 12], [7, 12], [7, 12], [7, 12], // 0000111xxxxx
  425. [7, 12], [7, 12], [7, 12], [7, 12],
  426. [7, 12], [7, 12], [7, 12], [7, 12],
  427. [7, 12], [7, 12], [7, 12], [7, 12],
  428. [7, 12], [7, 12], [7, 12], [7, 12],
  429. [7, 12], [7, 12], [7, 12], [7, 12],
  430. [7, 12], [7, 12], [7, 12], [7, 12],
  431. [7, 12], [7, 12], [7, 12], [7, 12]
  432. ];
  433. // prettier-ignore
  434. const blackTable3 = [
  435. [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 0000xx
  436. [6, 9], // 000100
  437. [6, 8], // 000101
  438. [5, 7], [5, 7], // 00011x
  439. [4, 6], [4, 6], [4, 6], [4, 6], // 0010xx
  440. [4, 5], [4, 5], [4, 5], [4, 5], // 0011xx
  441. [3, 1], [3, 1], [3, 1], [3, 1], // 010xxx
  442. [3, 1], [3, 1], [3, 1], [3, 1],
  443. [3, 4], [3, 4], [3, 4], [3, 4], // 011xxx
  444. [3, 4], [3, 4], [3, 4], [3, 4],
  445. [2, 3], [2, 3], [2, 3], [2, 3], // 10xxxx
  446. [2, 3], [2, 3], [2, 3], [2, 3],
  447. [2, 3], [2, 3], [2, 3], [2, 3],
  448. [2, 3], [2, 3], [2, 3], [2, 3],
  449. [2, 2], [2, 2], [2, 2], [2, 2], // 11xxxx
  450. [2, 2], [2, 2], [2, 2], [2, 2],
  451. [2, 2], [2, 2], [2, 2], [2, 2],
  452. [2, 2], [2, 2], [2, 2], [2, 2]
  453. ];
  454. /**
  455. * @param {CCITTFaxDecoderSource} source - The data which should be decoded.
  456. * @param {Object} [options] - Decoding options.
  457. */
  458. // eslint-disable-next-line no-shadow
  459. function CCITTFaxDecoder(source, options = {}) {
  460. if (!source || typeof source.next !== "function") {
  461. throw new Error('CCITTFaxDecoder - invalid "source" parameter.');
  462. }
  463. this.source = source;
  464. this.eof = false;
  465. this.encoding = options.K || 0;
  466. this.eoline = options.EndOfLine || false;
  467. this.byteAlign = options.EncodedByteAlign || false;
  468. this.columns = options.Columns || 1728;
  469. this.rows = options.Rows || 0;
  470. let eoblock = options.EndOfBlock;
  471. if (eoblock === null || eoblock === undefined) {
  472. eoblock = true;
  473. }
  474. this.eoblock = eoblock;
  475. this.black = options.BlackIs1 || false;
  476. this.codingLine = new Uint32Array(this.columns + 1);
  477. this.refLine = new Uint32Array(this.columns + 2);
  478. this.codingLine[0] = this.columns;
  479. this.codingPos = 0;
  480. this.row = 0;
  481. this.nextLine2D = this.encoding < 0;
  482. this.inputBits = 0;
  483. this.inputBuf = 0;
  484. this.outputBits = 0;
  485. this.rowsDone = false;
  486. let code1;
  487. while ((code1 = this._lookBits(12)) === 0) {
  488. this._eatBits(1);
  489. }
  490. if (code1 === 1) {
  491. this._eatBits(12);
  492. }
  493. if (this.encoding > 0) {
  494. this.nextLine2D = !this._lookBits(1);
  495. this._eatBits(1);
  496. }
  497. }
  498. CCITTFaxDecoder.prototype = {
  499. readNextChar() {
  500. if (this.eof) {
  501. return -1;
  502. }
  503. const refLine = this.refLine;
  504. const codingLine = this.codingLine;
  505. const columns = this.columns;
  506. let refPos, blackPixels, bits, i;
  507. if (this.outputBits === 0) {
  508. if (this.rowsDone) {
  509. this.eof = true;
  510. }
  511. if (this.eof) {
  512. return -1;
  513. }
  514. this.err = false;
  515. let code1, code2, code3;
  516. if (this.nextLine2D) {
  517. for (i = 0; codingLine[i] < columns; ++i) {
  518. refLine[i] = codingLine[i];
  519. }
  520. refLine[i++] = columns;
  521. refLine[i] = columns;
  522. codingLine[0] = 0;
  523. this.codingPos = 0;
  524. refPos = 0;
  525. blackPixels = 0;
  526. while (codingLine[this.codingPos] < columns) {
  527. code1 = this._getTwoDimCode();
  528. switch (code1) {
  529. case twoDimPass:
  530. this._addPixels(refLine[refPos + 1], blackPixels);
  531. if (refLine[refPos + 1] < columns) {
  532. refPos += 2;
  533. }
  534. break;
  535. case twoDimHoriz:
  536. code1 = code2 = 0;
  537. if (blackPixels) {
  538. do {
  539. code1 += code3 = this._getBlackCode();
  540. } while (code3 >= 64);
  541. do {
  542. code2 += code3 = this._getWhiteCode();
  543. } while (code3 >= 64);
  544. } else {
  545. do {
  546. code1 += code3 = this._getWhiteCode();
  547. } while (code3 >= 64);
  548. do {
  549. code2 += code3 = this._getBlackCode();
  550. } while (code3 >= 64);
  551. }
  552. this._addPixels(
  553. codingLine[this.codingPos] + code1,
  554. blackPixels
  555. );
  556. if (codingLine[this.codingPos] < columns) {
  557. this._addPixels(
  558. codingLine[this.codingPos] + code2,
  559. blackPixels ^ 1
  560. );
  561. }
  562. while (
  563. refLine[refPos] <= codingLine[this.codingPos] &&
  564. refLine[refPos] < columns
  565. ) {
  566. refPos += 2;
  567. }
  568. break;
  569. case twoDimVertR3:
  570. this._addPixels(refLine[refPos] + 3, blackPixels);
  571. blackPixels ^= 1;
  572. if (codingLine[this.codingPos] < columns) {
  573. ++refPos;
  574. while (
  575. refLine[refPos] <= codingLine[this.codingPos] &&
  576. refLine[refPos] < columns
  577. ) {
  578. refPos += 2;
  579. }
  580. }
  581. break;
  582. case twoDimVertR2:
  583. this._addPixels(refLine[refPos] + 2, blackPixels);
  584. blackPixels ^= 1;
  585. if (codingLine[this.codingPos] < columns) {
  586. ++refPos;
  587. while (
  588. refLine[refPos] <= codingLine[this.codingPos] &&
  589. refLine[refPos] < columns
  590. ) {
  591. refPos += 2;
  592. }
  593. }
  594. break;
  595. case twoDimVertR1:
  596. this._addPixels(refLine[refPos] + 1, blackPixels);
  597. blackPixels ^= 1;
  598. if (codingLine[this.codingPos] < columns) {
  599. ++refPos;
  600. while (
  601. refLine[refPos] <= codingLine[this.codingPos] &&
  602. refLine[refPos] < columns
  603. ) {
  604. refPos += 2;
  605. }
  606. }
  607. break;
  608. case twoDimVert0:
  609. this._addPixels(refLine[refPos], blackPixels);
  610. blackPixels ^= 1;
  611. if (codingLine[this.codingPos] < columns) {
  612. ++refPos;
  613. while (
  614. refLine[refPos] <= codingLine[this.codingPos] &&
  615. refLine[refPos] < columns
  616. ) {
  617. refPos += 2;
  618. }
  619. }
  620. break;
  621. case twoDimVertL3:
  622. this._addPixelsNeg(refLine[refPos] - 3, blackPixels);
  623. blackPixels ^= 1;
  624. if (codingLine[this.codingPos] < columns) {
  625. if (refPos > 0) {
  626. --refPos;
  627. } else {
  628. ++refPos;
  629. }
  630. while (
  631. refLine[refPos] <= codingLine[this.codingPos] &&
  632. refLine[refPos] < columns
  633. ) {
  634. refPos += 2;
  635. }
  636. }
  637. break;
  638. case twoDimVertL2:
  639. this._addPixelsNeg(refLine[refPos] - 2, blackPixels);
  640. blackPixels ^= 1;
  641. if (codingLine[this.codingPos] < columns) {
  642. if (refPos > 0) {
  643. --refPos;
  644. } else {
  645. ++refPos;
  646. }
  647. while (
  648. refLine[refPos] <= codingLine[this.codingPos] &&
  649. refLine[refPos] < columns
  650. ) {
  651. refPos += 2;
  652. }
  653. }
  654. break;
  655. case twoDimVertL1:
  656. this._addPixelsNeg(refLine[refPos] - 1, blackPixels);
  657. blackPixels ^= 1;
  658. if (codingLine[this.codingPos] < columns) {
  659. if (refPos > 0) {
  660. --refPos;
  661. } else {
  662. ++refPos;
  663. }
  664. while (
  665. refLine[refPos] <= codingLine[this.codingPos] &&
  666. refLine[refPos] < columns
  667. ) {
  668. refPos += 2;
  669. }
  670. }
  671. break;
  672. case ccittEOF:
  673. this._addPixels(columns, 0);
  674. this.eof = true;
  675. break;
  676. default:
  677. info("bad 2d code");
  678. this._addPixels(columns, 0);
  679. this.err = true;
  680. }
  681. }
  682. } else {
  683. codingLine[0] = 0;
  684. this.codingPos = 0;
  685. blackPixels = 0;
  686. while (codingLine[this.codingPos] < columns) {
  687. code1 = 0;
  688. if (blackPixels) {
  689. do {
  690. code1 += code3 = this._getBlackCode();
  691. } while (code3 >= 64);
  692. } else {
  693. do {
  694. code1 += code3 = this._getWhiteCode();
  695. } while (code3 >= 64);
  696. }
  697. this._addPixels(codingLine[this.codingPos] + code1, blackPixels);
  698. blackPixels ^= 1;
  699. }
  700. }
  701. let gotEOL = false;
  702. if (this.byteAlign) {
  703. this.inputBits &= ~7;
  704. }
  705. if (!this.eoblock && this.row === this.rows - 1) {
  706. this.rowsDone = true;
  707. } else {
  708. code1 = this._lookBits(12);
  709. if (this.eoline) {
  710. while (code1 !== ccittEOF && code1 !== 1) {
  711. this._eatBits(1);
  712. code1 = this._lookBits(12);
  713. }
  714. } else {
  715. while (code1 === 0) {
  716. this._eatBits(1);
  717. code1 = this._lookBits(12);
  718. }
  719. }
  720. if (code1 === 1) {
  721. this._eatBits(12);
  722. gotEOL = true;
  723. } else if (code1 === ccittEOF) {
  724. this.eof = true;
  725. }
  726. }
  727. if (!this.eof && this.encoding > 0 && !this.rowsDone) {
  728. this.nextLine2D = !this._lookBits(1);
  729. this._eatBits(1);
  730. }
  731. if (this.eoblock && gotEOL && this.byteAlign) {
  732. code1 = this._lookBits(12);
  733. if (code1 === 1) {
  734. this._eatBits(12);
  735. if (this.encoding > 0) {
  736. this._lookBits(1);
  737. this._eatBits(1);
  738. }
  739. if (this.encoding >= 0) {
  740. for (i = 0; i < 4; ++i) {
  741. code1 = this._lookBits(12);
  742. if (code1 !== 1) {
  743. info("bad rtc code: " + code1);
  744. }
  745. this._eatBits(12);
  746. if (this.encoding > 0) {
  747. this._lookBits(1);
  748. this._eatBits(1);
  749. }
  750. }
  751. }
  752. this.eof = true;
  753. }
  754. } else if (this.err && this.eoline) {
  755. while (true) {
  756. code1 = this._lookBits(13);
  757. if (code1 === ccittEOF) {
  758. this.eof = true;
  759. return -1;
  760. }
  761. if (code1 >> 1 === 1) {
  762. break;
  763. }
  764. this._eatBits(1);
  765. }
  766. this._eatBits(12);
  767. if (this.encoding > 0) {
  768. this._eatBits(1);
  769. this.nextLine2D = !(code1 & 1);
  770. }
  771. }
  772. if (codingLine[0] > 0) {
  773. this.outputBits = codingLine[(this.codingPos = 0)];
  774. } else {
  775. this.outputBits = codingLine[(this.codingPos = 1)];
  776. }
  777. this.row++;
  778. }
  779. let c;
  780. if (this.outputBits >= 8) {
  781. c = this.codingPos & 1 ? 0 : 0xff;
  782. this.outputBits -= 8;
  783. if (this.outputBits === 0 && codingLine[this.codingPos] < columns) {
  784. this.codingPos++;
  785. this.outputBits =
  786. codingLine[this.codingPos] - codingLine[this.codingPos - 1];
  787. }
  788. } else {
  789. bits = 8;
  790. c = 0;
  791. do {
  792. if (this.outputBits > bits) {
  793. c <<= bits;
  794. if (!(this.codingPos & 1)) {
  795. c |= 0xff >> (8 - bits);
  796. }
  797. this.outputBits -= bits;
  798. bits = 0;
  799. } else {
  800. c <<= this.outputBits;
  801. if (!(this.codingPos & 1)) {
  802. c |= 0xff >> (8 - this.outputBits);
  803. }
  804. bits -= this.outputBits;
  805. this.outputBits = 0;
  806. if (codingLine[this.codingPos] < columns) {
  807. this.codingPos++;
  808. this.outputBits =
  809. codingLine[this.codingPos] - codingLine[this.codingPos - 1];
  810. } else if (bits > 0) {
  811. c <<= bits;
  812. bits = 0;
  813. }
  814. }
  815. } while (bits);
  816. }
  817. if (this.black) {
  818. c ^= 0xff;
  819. }
  820. return c;
  821. },
  822. /**
  823. * @private
  824. */
  825. _addPixels(a1, blackPixels) {
  826. const codingLine = this.codingLine;
  827. let codingPos = this.codingPos;
  828. if (a1 > codingLine[codingPos]) {
  829. if (a1 > this.columns) {
  830. info("row is wrong length");
  831. this.err = true;
  832. a1 = this.columns;
  833. }
  834. if ((codingPos & 1) ^ blackPixels) {
  835. ++codingPos;
  836. }
  837. codingLine[codingPos] = a1;
  838. }
  839. this.codingPos = codingPos;
  840. },
  841. /**
  842. * @private
  843. */
  844. _addPixelsNeg(a1, blackPixels) {
  845. const codingLine = this.codingLine;
  846. let codingPos = this.codingPos;
  847. if (a1 > codingLine[codingPos]) {
  848. if (a1 > this.columns) {
  849. info("row is wrong length");
  850. this.err = true;
  851. a1 = this.columns;
  852. }
  853. if ((codingPos & 1) ^ blackPixels) {
  854. ++codingPos;
  855. }
  856. codingLine[codingPos] = a1;
  857. } else if (a1 < codingLine[codingPos]) {
  858. if (a1 < 0) {
  859. info("invalid code");
  860. this.err = true;
  861. a1 = 0;
  862. }
  863. while (codingPos > 0 && a1 < codingLine[codingPos - 1]) {
  864. --codingPos;
  865. }
  866. codingLine[codingPos] = a1;
  867. }
  868. this.codingPos = codingPos;
  869. },
  870. /**
  871. * This function returns the code found from the table.
  872. * The start and end parameters set the boundaries for searching the table.
  873. * The limit parameter is optional. Function returns an array with three
  874. * values. The first array element indicates whether a valid code is being
  875. * returned. The second array element is the actual code. The third array
  876. * element indicates whether EOF was reached.
  877. * @private
  878. */
  879. _findTableCode(start, end, table, limit) {
  880. const limitValue = limit || 0;
  881. for (let i = start; i <= end; ++i) {
  882. let code = this._lookBits(i);
  883. if (code === ccittEOF) {
  884. return [true, 1, false];
  885. }
  886. if (i < end) {
  887. code <<= end - i;
  888. }
  889. if (!limitValue || code >= limitValue) {
  890. const p = table[code - limitValue];
  891. if (p[0] === i) {
  892. this._eatBits(i);
  893. return [true, p[1], true];
  894. }
  895. }
  896. }
  897. return [false, 0, false];
  898. },
  899. /**
  900. * @private
  901. */
  902. _getTwoDimCode() {
  903. let code = 0;
  904. let p;
  905. if (this.eoblock) {
  906. code = this._lookBits(7);
  907. p = twoDimTable[code];
  908. if (p && p[0] > 0) {
  909. this._eatBits(p[0]);
  910. return p[1];
  911. }
  912. } else {
  913. const result = this._findTableCode(1, 7, twoDimTable);
  914. if (result[0] && result[2]) {
  915. return result[1];
  916. }
  917. }
  918. info("Bad two dim code");
  919. return ccittEOF;
  920. },
  921. /**
  922. * @private
  923. */
  924. _getWhiteCode() {
  925. let code = 0;
  926. let p;
  927. if (this.eoblock) {
  928. code = this._lookBits(12);
  929. if (code === ccittEOF) {
  930. return 1;
  931. }
  932. if (code >> 5 === 0) {
  933. p = whiteTable1[code];
  934. } else {
  935. p = whiteTable2[code >> 3];
  936. }
  937. if (p[0] > 0) {
  938. this._eatBits(p[0]);
  939. return p[1];
  940. }
  941. } else {
  942. let result = this._findTableCode(1, 9, whiteTable2);
  943. if (result[0]) {
  944. return result[1];
  945. }
  946. result = this._findTableCode(11, 12, whiteTable1);
  947. if (result[0]) {
  948. return result[1];
  949. }
  950. }
  951. info("bad white code");
  952. this._eatBits(1);
  953. return 1;
  954. },
  955. /**
  956. * @private
  957. */
  958. _getBlackCode() {
  959. let code, p;
  960. if (this.eoblock) {
  961. code = this._lookBits(13);
  962. if (code === ccittEOF) {
  963. return 1;
  964. }
  965. if (code >> 7 === 0) {
  966. p = blackTable1[code];
  967. } else if (code >> 9 === 0 && code >> 7 !== 0) {
  968. p = blackTable2[(code >> 1) - 64];
  969. } else {
  970. p = blackTable3[code >> 7];
  971. }
  972. if (p[0] > 0) {
  973. this._eatBits(p[0]);
  974. return p[1];
  975. }
  976. } else {
  977. let result = this._findTableCode(2, 6, blackTable3);
  978. if (result[0]) {
  979. return result[1];
  980. }
  981. result = this._findTableCode(7, 12, blackTable2, 64);
  982. if (result[0]) {
  983. return result[1];
  984. }
  985. result = this._findTableCode(10, 13, blackTable1);
  986. if (result[0]) {
  987. return result[1];
  988. }
  989. }
  990. info("bad black code");
  991. this._eatBits(1);
  992. return 1;
  993. },
  994. /**
  995. * @private
  996. */
  997. _lookBits(n) {
  998. let c;
  999. while (this.inputBits < n) {
  1000. if ((c = this.source.next()) === -1) {
  1001. if (this.inputBits === 0) {
  1002. return ccittEOF;
  1003. }
  1004. return (this.inputBuf << (n - this.inputBits)) & (0xffff >> (16 - n));
  1005. }
  1006. this.inputBuf = (this.inputBuf << 8) | c;
  1007. this.inputBits += 8;
  1008. }
  1009. return (this.inputBuf >> (this.inputBits - n)) & (0xffff >> (16 - n));
  1010. },
  1011. /**
  1012. * @private
  1013. */
  1014. _eatBits(n) {
  1015. if ((this.inputBits -= n) < 0) {
  1016. this.inputBits = 0;
  1017. }
  1018. },
  1019. };
  1020. return CCITTFaxDecoder;
  1021. })();
  1022. export { CCITTFaxDecoder };