@vaadin-component-factory/vcf-pdf-viewer 0.9.0 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +1 -1
  2. package/package.json +33 -18
  3. package/{src/display → pdfjs/dist}/display_utils.js +344 -139
  4. package/{src/display → pdfjs/dist}/fetch_stream.js +115 -97
  5. package/pdfjs/dist/get.js +1857 -0
  6. package/pdfjs/dist/index.js +767 -0
  7. package/pdfjs/dist/l10n_utils.js +140 -0
  8. package/{src/shared → pdfjs/dist}/message_handler.js +243 -259
  9. package/{src/display → pdfjs/dist}/network.js +149 -87
  10. package/{src/display/content_disposition.js → pdfjs/dist/network_utils.js} +167 -55
  11. package/{src/display → pdfjs/dist}/node_stream.js +133 -98
  12. package/pdfjs/dist/pdf.js +12778 -0
  13. package/pdfjs/dist/pdf_link_service.js +638 -0
  14. package/pdfjs/dist/pdf_rendering_queue.js +199 -0
  15. package/pdfjs/dist/pdf_thumbnail_viewer.js +819 -0
  16. package/pdfjs/dist/pdf_viewer.js +3598 -0
  17. package/pdfjs/dist/typeof.js +100 -0
  18. package/pdfjs/dist/ui_utils.js +1033 -0
  19. package/{src/shared → pdfjs/dist}/util.js +301 -287
  20. package/pdfjs/dist/worker.js +62813 -0
  21. package/src/vcf-pdf-viewer.js +77 -27
  22. package/theme/lumo/vcf-pdf-viewer-styles.js +1 -1
  23. package/theme/material/vcf-pdf-viewer.js +2 -2
  24. package/src/core/.eslintrc +0 -13
  25. package/src/core/annotation.js +0 -2948
  26. package/src/core/arithmetic_decoder.js +0 -182
  27. package/src/core/ascii_85_stream.js +0 -98
  28. package/src/core/ascii_hex_stream.js +0 -79
  29. package/src/core/base_stream.js +0 -110
  30. package/src/core/bidi.js +0 -438
  31. package/src/core/calibri_factors.js +0 -308
  32. package/src/core/catalog.js +0 -1459
  33. package/src/core/ccitt.js +0 -1062
  34. package/src/core/ccitt_stream.js +0 -60
  35. package/src/core/cff_font.js +0 -116
  36. package/src/core/cff_parser.js +0 -1949
  37. package/src/core/charsets.js +0 -119
  38. package/src/core/chunked_stream.js +0 -557
  39. package/src/core/cmap.js +0 -1039
  40. package/src/core/colorspace.js +0 -1533
  41. package/src/core/core_utils.js +0 -464
  42. package/src/core/crypto.js +0 -1900
  43. package/src/core/decode_stream.js +0 -170
  44. package/src/core/decrypt_stream.js +0 -59
  45. package/src/core/default_appearance.js +0 -99
  46. package/src/core/document.js +0 -1456
  47. package/src/core/encodings.js +0 -301
  48. package/src/core/evaluator.js +0 -4601
  49. package/src/core/file_spec.js +0 -108
  50. package/src/core/flate_stream.js +0 -402
  51. package/src/core/font_renderer.js +0 -882
  52. package/src/core/fonts.js +0 -3260
  53. package/src/core/fonts_utils.js +0 -221
  54. package/src/core/function.js +0 -1257
  55. package/src/core/glyf.js +0 -706
  56. package/src/core/glyphlist.js +0 -4558
  57. package/src/core/helvetica_factors.js +0 -353
  58. package/src/core/image.js +0 -802
  59. package/src/core/image_utils.js +0 -291
  60. package/src/core/jbig2.js +0 -2572
  61. package/src/core/jbig2_stream.js +0 -73
  62. package/src/core/jpeg_stream.js +0 -105
  63. package/src/core/jpg.js +0 -1416
  64. package/src/core/jpx.js +0 -2343
  65. package/src/core/jpx_stream.js +0 -87
  66. package/src/core/liberationsans_widths.js +0 -221
  67. package/src/core/lzw_stream.js +0 -150
  68. package/src/core/metadata_parser.js +0 -146
  69. package/src/core/metrics.js +0 -2970
  70. package/src/core/murmurhash3.js +0 -139
  71. package/src/core/myriadpro_factors.js +0 -290
  72. package/src/core/name_number_tree.js +0 -153
  73. package/src/core/object_loader.js +0 -149
  74. package/src/core/opentype_file_builder.js +0 -154
  75. package/src/core/operator_list.js +0 -734
  76. package/src/core/parser.js +0 -1416
  77. package/src/core/pattern.js +0 -985
  78. package/src/core/pdf_manager.js +0 -217
  79. package/src/core/predictor_stream.js +0 -238
  80. package/src/core/primitives.js +0 -402
  81. package/src/core/ps_parser.js +0 -272
  82. package/src/core/run_length_stream.js +0 -61
  83. package/src/core/segoeui_factors.js +0 -308
  84. package/src/core/standard_fonts.js +0 -817
  85. package/src/core/stream.js +0 -103
  86. package/src/core/struct_tree.js +0 -335
  87. package/src/core/to_unicode_map.js +0 -103
  88. package/src/core/type1_font.js +0 -421
  89. package/src/core/type1_parser.js +0 -776
  90. package/src/core/unicode.js +0 -1649
  91. package/src/core/worker.js +0 -848
  92. package/src/core/worker_stream.js +0 -135
  93. package/src/core/writer.js +0 -278
  94. package/src/core/xfa/bind.js +0 -652
  95. package/src/core/xfa/builder.js +0 -207
  96. package/src/core/xfa/config.js +0 -1926
  97. package/src/core/xfa/connection_set.js +0 -202
  98. package/src/core/xfa/data.js +0 -82
  99. package/src/core/xfa/datasets.js +0 -76
  100. package/src/core/xfa/factory.js +0 -111
  101. package/src/core/xfa/fonts.js +0 -181
  102. package/src/core/xfa/formcalc_lexer.js +0 -385
  103. package/src/core/xfa/formcalc_parser.js +0 -1340
  104. package/src/core/xfa/html_utils.js +0 -639
  105. package/src/core/xfa/layout.js +0 -383
  106. package/src/core/xfa/locale_set.js +0 -345
  107. package/src/core/xfa/namespaces.js +0 -81
  108. package/src/core/xfa/parser.js +0 -184
  109. package/src/core/xfa/setup.js +0 -38
  110. package/src/core/xfa/signature.js +0 -40
  111. package/src/core/xfa/som.js +0 -338
  112. package/src/core/xfa/stylesheet.js +0 -40
  113. package/src/core/xfa/template.js +0 -6260
  114. package/src/core/xfa/text.js +0 -290
  115. package/src/core/xfa/unknown.js +0 -29
  116. package/src/core/xfa/utils.js +0 -217
  117. package/src/core/xfa/xdp.js +0 -59
  118. package/src/core/xfa/xfa_object.js +0 -1130
  119. package/src/core/xfa/xhtml.js +0 -543
  120. package/src/core/xfa_fonts.js +0 -208
  121. package/src/core/xml_parser.js +0 -507
  122. package/src/core/xref.js +0 -899
  123. package/src/display/annotation_layer.js +0 -2107
  124. package/src/display/annotation_storage.js +0 -113
  125. package/src/display/api.js +0 -3292
  126. package/src/display/base_factory.js +0 -180
  127. package/src/display/canvas.js +0 -2828
  128. package/src/display/font_loader.js +0 -484
  129. package/src/display/metadata.js +0 -41
  130. package/src/display/network_utils.js +0 -100
  131. package/src/display/node_utils.js +0 -83
  132. package/src/display/optional_content_config.js +0 -189
  133. package/src/display/pattern_helper.js +0 -659
  134. package/src/display/svg.js +0 -1709
  135. package/src/display/text_layer.js +0 -847
  136. package/src/display/transport_stream.js +0 -303
  137. package/src/display/worker_options.js +0 -40
  138. package/src/display/xfa_layer.js +0 -204
  139. package/src/doc_helper.js +0 -25
  140. package/src/images/logo.svg +0 -41
  141. package/src/interfaces.js +0 -169
  142. package/src/license_header.js +0 -14
  143. package/src/license_header_libre.js +0 -21
  144. package/src/pdf.image_decoders.js +0 -46
  145. package/src/pdf.js +0 -146
  146. package/src/pdf.sandbox.external.js +0 -181
  147. package/src/pdf.sandbox.js +0 -151
  148. package/src/pdf.scripting.js +0 -25
  149. package/src/pdf.worker.entry.js +0 -19
  150. package/src/pdf.worker.js +0 -23
  151. package/src/scripting_api/aform.js +0 -608
  152. package/src/scripting_api/app.js +0 -621
  153. package/src/scripting_api/color.js +0 -129
  154. package/src/scripting_api/common.js +0 -58
  155. package/src/scripting_api/console.js +0 -38
  156. package/src/scripting_api/constants.js +0 -208
  157. package/src/scripting_api/doc.js +0 -1195
  158. package/src/scripting_api/error.js +0 -23
  159. package/src/scripting_api/event.js +0 -232
  160. package/src/scripting_api/field.js +0 -620
  161. package/src/scripting_api/fullscreen.js +0 -145
  162. package/src/scripting_api/initialization.js +0 -223
  163. package/src/scripting_api/pdf_object.js +0 -24
  164. package/src/scripting_api/print_params.js +0 -146
  165. package/src/scripting_api/proxy.js +0 -139
  166. package/src/scripting_api/thermometer.js +0 -69
  167. package/src/scripting_api/util.js +0 -581
  168. package/src/shared/.eslintrc +0 -13
  169. package/src/shared/cffStandardStrings.js +0 -311
  170. package/src/shared/compatibility.js +0 -114
  171. package/src/shared/fonts_utils.js +0 -429
  172. package/src/shared/is_node.js +0 -27
  173. package/src/shared/scripting_utils.js +0 -85
  174. package/src/worker_loader.js +0 -32
package/src/core/jbig2.js DELETED
@@ -1,2572 +0,0 @@
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
-
16
- import { BaseException, shadow } from "../shared/util.js";
17
- import { log2, readInt8, readUint16, readUint32 } from "./core_utils.js";
18
- import { ArithmeticDecoder } from "./arithmetic_decoder.js";
19
- import { CCITTFaxDecoder } from "./ccitt.js";
20
-
21
- class Jbig2Error extends BaseException {
22
- constructor(msg) {
23
- super(`JBIG2 error: ${msg}`);
24
- }
25
- }
26
-
27
- // Utility data structures
28
- class ContextCache {
29
- getContexts(id) {
30
- if (id in this) {
31
- return this[id];
32
- }
33
- return (this[id] = new Int8Array(1 << 16));
34
- }
35
- }
36
-
37
- class DecodingContext {
38
- constructor(data, start, end) {
39
- this.data = data;
40
- this.start = start;
41
- this.end = end;
42
- }
43
-
44
- get decoder() {
45
- const decoder = new ArithmeticDecoder(this.data, this.start, this.end);
46
- return shadow(this, "decoder", decoder);
47
- }
48
-
49
- get contextCache() {
50
- const cache = new ContextCache();
51
- return shadow(this, "contextCache", cache);
52
- }
53
- }
54
-
55
- // Annex A. Arithmetic Integer Decoding Procedure
56
- // A.2 Procedure for decoding values
57
- function decodeInteger(contextCache, procedure, decoder) {
58
- const contexts = contextCache.getContexts(procedure);
59
- let prev = 1;
60
-
61
- function readBits(length) {
62
- let v = 0;
63
- for (let i = 0; i < length; i++) {
64
- const bit = decoder.readBit(contexts, prev);
65
- prev = prev < 256 ? (prev << 1) | bit : (((prev << 1) | bit) & 511) | 256;
66
- v = (v << 1) | bit;
67
- }
68
- return v >>> 0;
69
- }
70
-
71
- const sign = readBits(1);
72
- // prettier-ignore
73
- /* eslint-disable no-nested-ternary */
74
- const value = readBits(1) ?
75
- (readBits(1) ?
76
- (readBits(1) ?
77
- (readBits(1) ?
78
- (readBits(1) ?
79
- (readBits(32) + 4436) :
80
- readBits(12) + 340) :
81
- readBits(8) + 84) :
82
- readBits(6) + 20) :
83
- readBits(4) + 4) :
84
- readBits(2);
85
- /* eslint-enable no-nested-ternary */
86
- if (sign === 0) {
87
- return value;
88
- } else if (value > 0) {
89
- return -value;
90
- }
91
- return null;
92
- }
93
-
94
- // A.3 The IAID decoding procedure
95
- function decodeIAID(contextCache, decoder, codeLength) {
96
- const contexts = contextCache.getContexts("IAID");
97
-
98
- let prev = 1;
99
- for (let i = 0; i < codeLength; i++) {
100
- const bit = decoder.readBit(contexts, prev);
101
- prev = (prev << 1) | bit;
102
- }
103
- if (codeLength < 31) {
104
- return prev & ((1 << codeLength) - 1);
105
- }
106
- return prev & 0x7fffffff;
107
- }
108
-
109
- // 7.3 Segment types
110
- const SegmentTypes = [
111
- "SymbolDictionary",
112
- null,
113
- null,
114
- null,
115
- "IntermediateTextRegion",
116
- null,
117
- "ImmediateTextRegion",
118
- "ImmediateLosslessTextRegion",
119
- null,
120
- null,
121
- null,
122
- null,
123
- null,
124
- null,
125
- null,
126
- null,
127
- "PatternDictionary",
128
- null,
129
- null,
130
- null,
131
- "IntermediateHalftoneRegion",
132
- null,
133
- "ImmediateHalftoneRegion",
134
- "ImmediateLosslessHalftoneRegion",
135
- null,
136
- null,
137
- null,
138
- null,
139
- null,
140
- null,
141
- null,
142
- null,
143
- null,
144
- null,
145
- null,
146
- null,
147
- "IntermediateGenericRegion",
148
- null,
149
- "ImmediateGenericRegion",
150
- "ImmediateLosslessGenericRegion",
151
- "IntermediateGenericRefinementRegion",
152
- null,
153
- "ImmediateGenericRefinementRegion",
154
- "ImmediateLosslessGenericRefinementRegion",
155
- null,
156
- null,
157
- null,
158
- null,
159
- "PageInformation",
160
- "EndOfPage",
161
- "EndOfStripe",
162
- "EndOfFile",
163
- "Profiles",
164
- "Tables",
165
- null,
166
- null,
167
- null,
168
- null,
169
- null,
170
- null,
171
- null,
172
- null,
173
- "Extension",
174
- ];
175
-
176
- const CodingTemplates = [
177
- [
178
- { x: -1, y: -2 },
179
- { x: 0, y: -2 },
180
- { x: 1, y: -2 },
181
- { x: -2, y: -1 },
182
- { x: -1, y: -1 },
183
- { x: 0, y: -1 },
184
- { x: 1, y: -1 },
185
- { x: 2, y: -1 },
186
- { x: -4, y: 0 },
187
- { x: -3, y: 0 },
188
- { x: -2, y: 0 },
189
- { x: -1, y: 0 },
190
- ],
191
- [
192
- { x: -1, y: -2 },
193
- { x: 0, y: -2 },
194
- { x: 1, y: -2 },
195
- { x: 2, y: -2 },
196
- { x: -2, y: -1 },
197
- { x: -1, y: -1 },
198
- { x: 0, y: -1 },
199
- { x: 1, y: -1 },
200
- { x: 2, y: -1 },
201
- { x: -3, y: 0 },
202
- { x: -2, y: 0 },
203
- { x: -1, y: 0 },
204
- ],
205
- [
206
- { x: -1, y: -2 },
207
- { x: 0, y: -2 },
208
- { x: 1, y: -2 },
209
- { x: -2, y: -1 },
210
- { x: -1, y: -1 },
211
- { x: 0, y: -1 },
212
- { x: 1, y: -1 },
213
- { x: -2, y: 0 },
214
- { x: -1, y: 0 },
215
- ],
216
- [
217
- { x: -3, y: -1 },
218
- { x: -2, y: -1 },
219
- { x: -1, y: -1 },
220
- { x: 0, y: -1 },
221
- { x: 1, y: -1 },
222
- { x: -4, y: 0 },
223
- { x: -3, y: 0 },
224
- { x: -2, y: 0 },
225
- { x: -1, y: 0 },
226
- ],
227
- ];
228
-
229
- const RefinementTemplates = [
230
- {
231
- coding: [
232
- { x: 0, y: -1 },
233
- { x: 1, y: -1 },
234
- { x: -1, y: 0 },
235
- ],
236
- reference: [
237
- { x: 0, y: -1 },
238
- { x: 1, y: -1 },
239
- { x: -1, y: 0 },
240
- { x: 0, y: 0 },
241
- { x: 1, y: 0 },
242
- { x: -1, y: 1 },
243
- { x: 0, y: 1 },
244
- { x: 1, y: 1 },
245
- ],
246
- },
247
- {
248
- coding: [
249
- { x: -1, y: -1 },
250
- { x: 0, y: -1 },
251
- { x: 1, y: -1 },
252
- { x: -1, y: 0 },
253
- ],
254
- reference: [
255
- { x: 0, y: -1 },
256
- { x: -1, y: 0 },
257
- { x: 0, y: 0 },
258
- { x: 1, y: 0 },
259
- { x: 0, y: 1 },
260
- { x: 1, y: 1 },
261
- ],
262
- },
263
- ];
264
-
265
- // See 6.2.5.7 Decoding the bitmap.
266
- const ReusedContexts = [
267
- 0x9b25, // 10011 0110010 0101
268
- 0x0795, // 0011 110010 101
269
- 0x00e5, // 001 11001 01
270
- 0x0195, // 011001 0101
271
- ];
272
-
273
- const RefinementReusedContexts = [
274
- 0x0020, // '000' + '0' (coding) + '00010000' + '0' (reference)
275
- 0x0008, // '0000' + '001000'
276
- ];
277
-
278
- function decodeBitmapTemplate0(width, height, decodingContext) {
279
- const decoder = decodingContext.decoder;
280
- const contexts = decodingContext.contextCache.getContexts("GB");
281
- const bitmap = [];
282
- let contextLabel, i, j, pixel, row, row1, row2;
283
-
284
- // ...ooooo....
285
- // ..ooooooo... Context template for current pixel (X)
286
- // .ooooX...... (concatenate values of 'o'-pixels to get contextLabel)
287
- const OLD_PIXEL_MASK = 0x7bf7; // 01111 0111111 0111
288
-
289
- for (i = 0; i < height; i++) {
290
- row = bitmap[i] = new Uint8Array(width);
291
- row1 = i < 1 ? row : bitmap[i - 1];
292
- row2 = i < 2 ? row : bitmap[i - 2];
293
-
294
- // At the beginning of each row:
295
- // Fill contextLabel with pixels that are above/right of (X)
296
- contextLabel =
297
- (row2[0] << 13) |
298
- (row2[1] << 12) |
299
- (row2[2] << 11) |
300
- (row1[0] << 7) |
301
- (row1[1] << 6) |
302
- (row1[2] << 5) |
303
- (row1[3] << 4);
304
-
305
- for (j = 0; j < width; j++) {
306
- row[j] = pixel = decoder.readBit(contexts, contextLabel);
307
-
308
- // At each pixel: Clear contextLabel pixels that are shifted
309
- // out of the context, then add new ones.
310
- contextLabel =
311
- ((contextLabel & OLD_PIXEL_MASK) << 1) |
312
- (j + 3 < width ? row2[j + 3] << 11 : 0) |
313
- (j + 4 < width ? row1[j + 4] << 4 : 0) |
314
- pixel;
315
- }
316
- }
317
-
318
- return bitmap;
319
- }
320
-
321
- // 6.2 Generic Region Decoding Procedure
322
- function decodeBitmap(
323
- mmr,
324
- width,
325
- height,
326
- templateIndex,
327
- prediction,
328
- skip,
329
- at,
330
- decodingContext
331
- ) {
332
- if (mmr) {
333
- const input = new Reader(
334
- decodingContext.data,
335
- decodingContext.start,
336
- decodingContext.end
337
- );
338
- return decodeMMRBitmap(input, width, height, false);
339
- }
340
-
341
- // Use optimized version for the most common case
342
- if (
343
- templateIndex === 0 &&
344
- !skip &&
345
- !prediction &&
346
- at.length === 4 &&
347
- at[0].x === 3 &&
348
- at[0].y === -1 &&
349
- at[1].x === -3 &&
350
- at[1].y === -1 &&
351
- at[2].x === 2 &&
352
- at[2].y === -2 &&
353
- at[3].x === -2 &&
354
- at[3].y === -2
355
- ) {
356
- return decodeBitmapTemplate0(width, height, decodingContext);
357
- }
358
-
359
- const useskip = !!skip;
360
- const template = CodingTemplates[templateIndex].concat(at);
361
-
362
- // Sorting is non-standard, and it is not required. But sorting increases
363
- // the number of template bits that can be reused from the previous
364
- // contextLabel in the main loop.
365
- template.sort(function (a, b) {
366
- return a.y - b.y || a.x - b.x;
367
- });
368
-
369
- const templateLength = template.length;
370
- const templateX = new Int8Array(templateLength);
371
- const templateY = new Int8Array(templateLength);
372
- const changingTemplateEntries = [];
373
- let reuseMask = 0,
374
- minX = 0,
375
- maxX = 0,
376
- minY = 0;
377
- let c, k;
378
-
379
- for (k = 0; k < templateLength; k++) {
380
- templateX[k] = template[k].x;
381
- templateY[k] = template[k].y;
382
- minX = Math.min(minX, template[k].x);
383
- maxX = Math.max(maxX, template[k].x);
384
- minY = Math.min(minY, template[k].y);
385
- // Check if the template pixel appears in two consecutive context labels,
386
- // so it can be reused. Otherwise, we add it to the list of changing
387
- // template entries.
388
- if (
389
- k < templateLength - 1 &&
390
- template[k].y === template[k + 1].y &&
391
- template[k].x === template[k + 1].x - 1
392
- ) {
393
- reuseMask |= 1 << (templateLength - 1 - k);
394
- } else {
395
- changingTemplateEntries.push(k);
396
- }
397
- }
398
- const changingEntriesLength = changingTemplateEntries.length;
399
-
400
- const changingTemplateX = new Int8Array(changingEntriesLength);
401
- const changingTemplateY = new Int8Array(changingEntriesLength);
402
- const changingTemplateBit = new Uint16Array(changingEntriesLength);
403
- for (c = 0; c < changingEntriesLength; c++) {
404
- k = changingTemplateEntries[c];
405
- changingTemplateX[c] = template[k].x;
406
- changingTemplateY[c] = template[k].y;
407
- changingTemplateBit[c] = 1 << (templateLength - 1 - k);
408
- }
409
-
410
- // Get the safe bounding box edges from the width, height, minX, maxX, minY
411
- const sbb_left = -minX;
412
- const sbb_top = -minY;
413
- const sbb_right = width - maxX;
414
-
415
- const pseudoPixelContext = ReusedContexts[templateIndex];
416
- let row = new Uint8Array(width);
417
- const bitmap = [];
418
-
419
- const decoder = decodingContext.decoder;
420
- const contexts = decodingContext.contextCache.getContexts("GB");
421
-
422
- let ltp = 0,
423
- j,
424
- i0,
425
- j0,
426
- contextLabel = 0,
427
- bit,
428
- shift;
429
- for (let i = 0; i < height; i++) {
430
- if (prediction) {
431
- const sltp = decoder.readBit(contexts, pseudoPixelContext);
432
- ltp ^= sltp;
433
- if (ltp) {
434
- bitmap.push(row); // duplicate previous row
435
- continue;
436
- }
437
- }
438
- row = new Uint8Array(row);
439
- bitmap.push(row);
440
- for (j = 0; j < width; j++) {
441
- if (useskip && skip[i][j]) {
442
- row[j] = 0;
443
- continue;
444
- }
445
- // Are we in the middle of a scanline, so we can reuse contextLabel
446
- // bits?
447
- if (j >= sbb_left && j < sbb_right && i >= sbb_top) {
448
- // If yes, we can just shift the bits that are reusable and only
449
- // fetch the remaining ones.
450
- contextLabel = (contextLabel << 1) & reuseMask;
451
- for (k = 0; k < changingEntriesLength; k++) {
452
- i0 = i + changingTemplateY[k];
453
- j0 = j + changingTemplateX[k];
454
- bit = bitmap[i0][j0];
455
- if (bit) {
456
- bit = changingTemplateBit[k];
457
- contextLabel |= bit;
458
- }
459
- }
460
- } else {
461
- // compute the contextLabel from scratch
462
- contextLabel = 0;
463
- shift = templateLength - 1;
464
- for (k = 0; k < templateLength; k++, shift--) {
465
- j0 = j + templateX[k];
466
- if (j0 >= 0 && j0 < width) {
467
- i0 = i + templateY[k];
468
- if (i0 >= 0) {
469
- bit = bitmap[i0][j0];
470
- if (bit) {
471
- contextLabel |= bit << shift;
472
- }
473
- }
474
- }
475
- }
476
- }
477
- const pixel = decoder.readBit(contexts, contextLabel);
478
- row[j] = pixel;
479
- }
480
- }
481
- return bitmap;
482
- }
483
-
484
- // 6.3.2 Generic Refinement Region Decoding Procedure
485
- function decodeRefinement(
486
- width,
487
- height,
488
- templateIndex,
489
- referenceBitmap,
490
- offsetX,
491
- offsetY,
492
- prediction,
493
- at,
494
- decodingContext
495
- ) {
496
- let codingTemplate = RefinementTemplates[templateIndex].coding;
497
- if (templateIndex === 0) {
498
- codingTemplate = codingTemplate.concat([at[0]]);
499
- }
500
- const codingTemplateLength = codingTemplate.length;
501
- const codingTemplateX = new Int32Array(codingTemplateLength);
502
- const codingTemplateY = new Int32Array(codingTemplateLength);
503
- let k;
504
- for (k = 0; k < codingTemplateLength; k++) {
505
- codingTemplateX[k] = codingTemplate[k].x;
506
- codingTemplateY[k] = codingTemplate[k].y;
507
- }
508
-
509
- let referenceTemplate = RefinementTemplates[templateIndex].reference;
510
- if (templateIndex === 0) {
511
- referenceTemplate = referenceTemplate.concat([at[1]]);
512
- }
513
- const referenceTemplateLength = referenceTemplate.length;
514
- const referenceTemplateX = new Int32Array(referenceTemplateLength);
515
- const referenceTemplateY = new Int32Array(referenceTemplateLength);
516
- for (k = 0; k < referenceTemplateLength; k++) {
517
- referenceTemplateX[k] = referenceTemplate[k].x;
518
- referenceTemplateY[k] = referenceTemplate[k].y;
519
- }
520
- const referenceWidth = referenceBitmap[0].length;
521
- const referenceHeight = referenceBitmap.length;
522
-
523
- const pseudoPixelContext = RefinementReusedContexts[templateIndex];
524
- const bitmap = [];
525
-
526
- const decoder = decodingContext.decoder;
527
- const contexts = decodingContext.contextCache.getContexts("GR");
528
-
529
- let ltp = 0;
530
- for (let i = 0; i < height; i++) {
531
- if (prediction) {
532
- const sltp = decoder.readBit(contexts, pseudoPixelContext);
533
- ltp ^= sltp;
534
- if (ltp) {
535
- throw new Jbig2Error("prediction is not supported");
536
- }
537
- }
538
- const row = new Uint8Array(width);
539
- bitmap.push(row);
540
- for (let j = 0; j < width; j++) {
541
- let i0, j0;
542
- let contextLabel = 0;
543
- for (k = 0; k < codingTemplateLength; k++) {
544
- i0 = i + codingTemplateY[k];
545
- j0 = j + codingTemplateX[k];
546
- if (i0 < 0 || j0 < 0 || j0 >= width) {
547
- contextLabel <<= 1; // out of bound pixel
548
- } else {
549
- contextLabel = (contextLabel << 1) | bitmap[i0][j0];
550
- }
551
- }
552
- for (k = 0; k < referenceTemplateLength; k++) {
553
- i0 = i + referenceTemplateY[k] - offsetY;
554
- j0 = j + referenceTemplateX[k] - offsetX;
555
- if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) {
556
- contextLabel <<= 1; // out of bound pixel
557
- } else {
558
- contextLabel = (contextLabel << 1) | referenceBitmap[i0][j0];
559
- }
560
- }
561
- const pixel = decoder.readBit(contexts, contextLabel);
562
- row[j] = pixel;
563
- }
564
- }
565
-
566
- return bitmap;
567
- }
568
-
569
- // 6.5.5 Decoding the symbol dictionary
570
- function decodeSymbolDictionary(
571
- huffman,
572
- refinement,
573
- symbols,
574
- numberOfNewSymbols,
575
- numberOfExportedSymbols,
576
- huffmanTables,
577
- templateIndex,
578
- at,
579
- refinementTemplateIndex,
580
- refinementAt,
581
- decodingContext,
582
- huffmanInput
583
- ) {
584
- if (huffman && refinement) {
585
- throw new Jbig2Error("symbol refinement with Huffman is not supported");
586
- }
587
-
588
- const newSymbols = [];
589
- let currentHeight = 0;
590
- let symbolCodeLength = log2(symbols.length + numberOfNewSymbols);
591
-
592
- const decoder = decodingContext.decoder;
593
- const contextCache = decodingContext.contextCache;
594
- let tableB1, symbolWidths;
595
- if (huffman) {
596
- tableB1 = getStandardTable(1); // standard table B.1
597
- symbolWidths = [];
598
- symbolCodeLength = Math.max(symbolCodeLength, 1); // 6.5.8.2.3
599
- }
600
-
601
- while (newSymbols.length < numberOfNewSymbols) {
602
- const deltaHeight = huffman
603
- ? huffmanTables.tableDeltaHeight.decode(huffmanInput)
604
- : decodeInteger(contextCache, "IADH", decoder); // 6.5.6
605
- currentHeight += deltaHeight;
606
- let currentWidth = 0,
607
- totalWidth = 0;
608
- const firstSymbol = huffman ? symbolWidths.length : 0;
609
- while (true) {
610
- const deltaWidth = huffman
611
- ? huffmanTables.tableDeltaWidth.decode(huffmanInput)
612
- : decodeInteger(contextCache, "IADW", decoder); // 6.5.7
613
- if (deltaWidth === null) {
614
- break; // OOB
615
- }
616
- currentWidth += deltaWidth;
617
- totalWidth += currentWidth;
618
- let bitmap;
619
- if (refinement) {
620
- // 6.5.8.2 Refinement/aggregate-coded symbol bitmap
621
- const numberOfInstances = decodeInteger(contextCache, "IAAI", decoder);
622
- if (numberOfInstances > 1) {
623
- bitmap = decodeTextRegion(
624
- huffman,
625
- refinement,
626
- currentWidth,
627
- currentHeight,
628
- 0,
629
- numberOfInstances,
630
- 1, // strip size
631
- symbols.concat(newSymbols),
632
- symbolCodeLength,
633
- 0, // transposed
634
- 0, // ds offset
635
- 1, // top left 7.4.3.1.1
636
- 0, // OR operator
637
- huffmanTables,
638
- refinementTemplateIndex,
639
- refinementAt,
640
- decodingContext,
641
- 0,
642
- huffmanInput
643
- );
644
- } else {
645
- const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength);
646
- const rdx = decodeInteger(contextCache, "IARDX", decoder); // 6.4.11.3
647
- const rdy = decodeInteger(contextCache, "IARDY", decoder); // 6.4.11.4
648
- const symbol =
649
- symbolId < symbols.length
650
- ? symbols[symbolId]
651
- : newSymbols[symbolId - symbols.length];
652
- bitmap = decodeRefinement(
653
- currentWidth,
654
- currentHeight,
655
- refinementTemplateIndex,
656
- symbol,
657
- rdx,
658
- rdy,
659
- false,
660
- refinementAt,
661
- decodingContext
662
- );
663
- }
664
- newSymbols.push(bitmap);
665
- } else if (huffman) {
666
- // Store only symbol width and decode a collective bitmap when the
667
- // height class is done.
668
- symbolWidths.push(currentWidth);
669
- } else {
670
- // 6.5.8.1 Direct-coded symbol bitmap
671
- bitmap = decodeBitmap(
672
- false,
673
- currentWidth,
674
- currentHeight,
675
- templateIndex,
676
- false,
677
- null,
678
- at,
679
- decodingContext
680
- );
681
- newSymbols.push(bitmap);
682
- }
683
- }
684
- if (huffman && !refinement) {
685
- // 6.5.9 Height class collective bitmap
686
- const bitmapSize = huffmanTables.tableBitmapSize.decode(huffmanInput);
687
- huffmanInput.byteAlign();
688
- let collectiveBitmap;
689
- if (bitmapSize === 0) {
690
- // Uncompressed collective bitmap
691
- collectiveBitmap = readUncompressedBitmap(
692
- huffmanInput,
693
- totalWidth,
694
- currentHeight
695
- );
696
- } else {
697
- // MMR collective bitmap
698
- const originalEnd = huffmanInput.end;
699
- const bitmapEnd = huffmanInput.position + bitmapSize;
700
- huffmanInput.end = bitmapEnd;
701
- collectiveBitmap = decodeMMRBitmap(
702
- huffmanInput,
703
- totalWidth,
704
- currentHeight,
705
- false
706
- );
707
- huffmanInput.end = originalEnd;
708
- huffmanInput.position = bitmapEnd;
709
- }
710
- const numberOfSymbolsDecoded = symbolWidths.length;
711
- if (firstSymbol === numberOfSymbolsDecoded - 1) {
712
- // collectiveBitmap is a single symbol.
713
- newSymbols.push(collectiveBitmap);
714
- } else {
715
- // Divide collectiveBitmap into symbols.
716
- let i,
717
- y,
718
- xMin = 0,
719
- xMax,
720
- bitmapWidth,
721
- symbolBitmap;
722
- for (i = firstSymbol; i < numberOfSymbolsDecoded; i++) {
723
- bitmapWidth = symbolWidths[i];
724
- xMax = xMin + bitmapWidth;
725
- symbolBitmap = [];
726
- for (y = 0; y < currentHeight; y++) {
727
- symbolBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));
728
- }
729
- newSymbols.push(symbolBitmap);
730
- xMin = xMax;
731
- }
732
- }
733
- }
734
- }
735
-
736
- // 6.5.10 Exported symbols
737
- const exportedSymbols = [],
738
- flags = [];
739
- let currentFlag = false,
740
- i,
741
- ii;
742
- const totalSymbolsLength = symbols.length + numberOfNewSymbols;
743
- while (flags.length < totalSymbolsLength) {
744
- let runLength = huffman
745
- ? tableB1.decode(huffmanInput)
746
- : decodeInteger(contextCache, "IAEX", decoder);
747
- while (runLength--) {
748
- flags.push(currentFlag);
749
- }
750
- currentFlag = !currentFlag;
751
- }
752
- for (i = 0, ii = symbols.length; i < ii; i++) {
753
- if (flags[i]) {
754
- exportedSymbols.push(symbols[i]);
755
- }
756
- }
757
- for (let j = 0; j < numberOfNewSymbols; i++, j++) {
758
- if (flags[i]) {
759
- exportedSymbols.push(newSymbols[j]);
760
- }
761
- }
762
- return exportedSymbols;
763
- }
764
-
765
- function decodeTextRegion(
766
- huffman,
767
- refinement,
768
- width,
769
- height,
770
- defaultPixelValue,
771
- numberOfSymbolInstances,
772
- stripSize,
773
- inputSymbols,
774
- symbolCodeLength,
775
- transposed,
776
- dsOffset,
777
- referenceCorner,
778
- combinationOperator,
779
- huffmanTables,
780
- refinementTemplateIndex,
781
- refinementAt,
782
- decodingContext,
783
- logStripSize,
784
- huffmanInput
785
- ) {
786
- if (huffman && refinement) {
787
- throw new Jbig2Error("refinement with Huffman is not supported");
788
- }
789
-
790
- // Prepare bitmap
791
- const bitmap = [];
792
- let i, row;
793
- for (i = 0; i < height; i++) {
794
- row = new Uint8Array(width);
795
- if (defaultPixelValue) {
796
- for (let j = 0; j < width; j++) {
797
- row[j] = defaultPixelValue;
798
- }
799
- }
800
- bitmap.push(row);
801
- }
802
-
803
- const decoder = decodingContext.decoder;
804
- const contextCache = decodingContext.contextCache;
805
-
806
- let stripT = huffman
807
- ? -huffmanTables.tableDeltaT.decode(huffmanInput)
808
- : -decodeInteger(contextCache, "IADT", decoder); // 6.4.6
809
- let firstS = 0;
810
- i = 0;
811
- while (i < numberOfSymbolInstances) {
812
- const deltaT = huffman
813
- ? huffmanTables.tableDeltaT.decode(huffmanInput)
814
- : decodeInteger(contextCache, "IADT", decoder); // 6.4.6
815
- stripT += deltaT;
816
-
817
- const deltaFirstS = huffman
818
- ? huffmanTables.tableFirstS.decode(huffmanInput)
819
- : decodeInteger(contextCache, "IAFS", decoder); // 6.4.7
820
- firstS += deltaFirstS;
821
- let currentS = firstS;
822
- do {
823
- let currentT = 0; // 6.4.9
824
- if (stripSize > 1) {
825
- currentT = huffman
826
- ? huffmanInput.readBits(logStripSize)
827
- : decodeInteger(contextCache, "IAIT", decoder);
828
- }
829
- const t = stripSize * stripT + currentT;
830
- const symbolId = huffman
831
- ? huffmanTables.symbolIDTable.decode(huffmanInput)
832
- : decodeIAID(contextCache, decoder, symbolCodeLength);
833
- const applyRefinement =
834
- refinement &&
835
- (huffman
836
- ? huffmanInput.readBit()
837
- : decodeInteger(contextCache, "IARI", decoder));
838
- let symbolBitmap = inputSymbols[symbolId];
839
- let symbolWidth = symbolBitmap[0].length;
840
- let symbolHeight = symbolBitmap.length;
841
- if (applyRefinement) {
842
- const rdw = decodeInteger(contextCache, "IARDW", decoder); // 6.4.11.1
843
- const rdh = decodeInteger(contextCache, "IARDH", decoder); // 6.4.11.2
844
- const rdx = decodeInteger(contextCache, "IARDX", decoder); // 6.4.11.3
845
- const rdy = decodeInteger(contextCache, "IARDY", decoder); // 6.4.11.4
846
- symbolWidth += rdw;
847
- symbolHeight += rdh;
848
- symbolBitmap = decodeRefinement(
849
- symbolWidth,
850
- symbolHeight,
851
- refinementTemplateIndex,
852
- symbolBitmap,
853
- (rdw >> 1) + rdx,
854
- (rdh >> 1) + rdy,
855
- false,
856
- refinementAt,
857
- decodingContext
858
- );
859
- }
860
- const offsetT = t - (referenceCorner & 1 ? 0 : symbolHeight - 1);
861
- const offsetS = currentS - (referenceCorner & 2 ? symbolWidth - 1 : 0);
862
- let s2, t2, symbolRow;
863
- if (transposed) {
864
- // Place Symbol Bitmap from T1,S1
865
- for (s2 = 0; s2 < symbolHeight; s2++) {
866
- row = bitmap[offsetS + s2];
867
- if (!row) {
868
- continue;
869
- }
870
- symbolRow = symbolBitmap[s2];
871
- // To ignore Parts of Symbol bitmap which goes
872
- // outside bitmap region
873
- const maxWidth = Math.min(width - offsetT, symbolWidth);
874
- switch (combinationOperator) {
875
- case 0: // OR
876
- for (t2 = 0; t2 < maxWidth; t2++) {
877
- row[offsetT + t2] |= symbolRow[t2];
878
- }
879
- break;
880
- case 2: // XOR
881
- for (t2 = 0; t2 < maxWidth; t2++) {
882
- row[offsetT + t2] ^= symbolRow[t2];
883
- }
884
- break;
885
- default:
886
- throw new Jbig2Error(
887
- `operator ${combinationOperator} is not supported`
888
- );
889
- }
890
- }
891
- currentS += symbolHeight - 1;
892
- } else {
893
- for (t2 = 0; t2 < symbolHeight; t2++) {
894
- row = bitmap[offsetT + t2];
895
- if (!row) {
896
- continue;
897
- }
898
- symbolRow = symbolBitmap[t2];
899
- switch (combinationOperator) {
900
- case 0: // OR
901
- for (s2 = 0; s2 < symbolWidth; s2++) {
902
- row[offsetS + s2] |= symbolRow[s2];
903
- }
904
- break;
905
- case 2: // XOR
906
- for (s2 = 0; s2 < symbolWidth; s2++) {
907
- row[offsetS + s2] ^= symbolRow[s2];
908
- }
909
- break;
910
- default:
911
- throw new Jbig2Error(
912
- `operator ${combinationOperator} is not supported`
913
- );
914
- }
915
- }
916
- currentS += symbolWidth - 1;
917
- }
918
- i++;
919
- const deltaS = huffman
920
- ? huffmanTables.tableDeltaS.decode(huffmanInput)
921
- : decodeInteger(contextCache, "IADS", decoder); // 6.4.8
922
- if (deltaS === null) {
923
- break; // OOB
924
- }
925
- currentS += deltaS + dsOffset;
926
- } while (true);
927
- }
928
- return bitmap;
929
- }
930
-
931
- function decodePatternDictionary(
932
- mmr,
933
- patternWidth,
934
- patternHeight,
935
- maxPatternIndex,
936
- template,
937
- decodingContext
938
- ) {
939
- const at = [];
940
- if (!mmr) {
941
- at.push({
942
- x: -patternWidth,
943
- y: 0,
944
- });
945
- if (template === 0) {
946
- at.push(
947
- {
948
- x: -3,
949
- y: -1,
950
- },
951
- {
952
- x: 2,
953
- y: -2,
954
- },
955
- {
956
- x: -2,
957
- y: -2,
958
- }
959
- );
960
- }
961
- }
962
- const collectiveWidth = (maxPatternIndex + 1) * patternWidth;
963
- const collectiveBitmap = decodeBitmap(
964
- mmr,
965
- collectiveWidth,
966
- patternHeight,
967
- template,
968
- false,
969
- null,
970
- at,
971
- decodingContext
972
- );
973
- // Divide collective bitmap into patterns.
974
- const patterns = [];
975
- for (let i = 0; i <= maxPatternIndex; i++) {
976
- const patternBitmap = [];
977
- const xMin = patternWidth * i;
978
- const xMax = xMin + patternWidth;
979
- for (let y = 0; y < patternHeight; y++) {
980
- patternBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));
981
- }
982
- patterns.push(patternBitmap);
983
- }
984
- return patterns;
985
- }
986
-
987
- function decodeHalftoneRegion(
988
- mmr,
989
- patterns,
990
- template,
991
- regionWidth,
992
- regionHeight,
993
- defaultPixelValue,
994
- enableSkip,
995
- combinationOperator,
996
- gridWidth,
997
- gridHeight,
998
- gridOffsetX,
999
- gridOffsetY,
1000
- gridVectorX,
1001
- gridVectorY,
1002
- decodingContext
1003
- ) {
1004
- const skip = null;
1005
- if (enableSkip) {
1006
- throw new Jbig2Error("skip is not supported");
1007
- }
1008
- if (combinationOperator !== 0) {
1009
- throw new Jbig2Error(
1010
- `operator "${combinationOperator}" is not supported in halftone region`
1011
- );
1012
- }
1013
-
1014
- // Prepare bitmap.
1015
- const regionBitmap = [];
1016
- let i, j, row;
1017
- for (i = 0; i < regionHeight; i++) {
1018
- row = new Uint8Array(regionWidth);
1019
- if (defaultPixelValue) {
1020
- for (j = 0; j < regionWidth; j++) {
1021
- row[j] = defaultPixelValue;
1022
- }
1023
- }
1024
- regionBitmap.push(row);
1025
- }
1026
-
1027
- const numberOfPatterns = patterns.length;
1028
- const pattern0 = patterns[0];
1029
- const patternWidth = pattern0[0].length,
1030
- patternHeight = pattern0.length;
1031
- const bitsPerValue = log2(numberOfPatterns);
1032
- const at = [];
1033
- if (!mmr) {
1034
- at.push({
1035
- x: template <= 1 ? 3 : 2,
1036
- y: -1,
1037
- });
1038
- if (template === 0) {
1039
- at.push(
1040
- {
1041
- x: -3,
1042
- y: -1,
1043
- },
1044
- {
1045
- x: 2,
1046
- y: -2,
1047
- },
1048
- {
1049
- x: -2,
1050
- y: -2,
1051
- }
1052
- );
1053
- }
1054
- }
1055
- // Annex C. Gray-scale Image Decoding Procedure.
1056
- const grayScaleBitPlanes = [];
1057
- let mmrInput, bitmap;
1058
- if (mmr) {
1059
- // MMR bit planes are in one continuous stream. Only EOFB codes indicate
1060
- // the end of each bitmap, so EOFBs must be decoded.
1061
- mmrInput = new Reader(
1062
- decodingContext.data,
1063
- decodingContext.start,
1064
- decodingContext.end
1065
- );
1066
- }
1067
- for (i = bitsPerValue - 1; i >= 0; i--) {
1068
- if (mmr) {
1069
- bitmap = decodeMMRBitmap(mmrInput, gridWidth, gridHeight, true);
1070
- } else {
1071
- bitmap = decodeBitmap(
1072
- false,
1073
- gridWidth,
1074
- gridHeight,
1075
- template,
1076
- false,
1077
- skip,
1078
- at,
1079
- decodingContext
1080
- );
1081
- }
1082
- grayScaleBitPlanes[i] = bitmap;
1083
- }
1084
- // 6.6.5.2 Rendering the patterns.
1085
- let mg, ng, bit, patternIndex, patternBitmap, x, y, patternRow, regionRow;
1086
- for (mg = 0; mg < gridHeight; mg++) {
1087
- for (ng = 0; ng < gridWidth; ng++) {
1088
- bit = 0;
1089
- patternIndex = 0;
1090
- for (j = bitsPerValue - 1; j >= 0; j--) {
1091
- bit ^= grayScaleBitPlanes[j][mg][ng]; // Gray decoding
1092
- patternIndex |= bit << j;
1093
- }
1094
- patternBitmap = patterns[patternIndex];
1095
- x = (gridOffsetX + mg * gridVectorY + ng * gridVectorX) >> 8;
1096
- y = (gridOffsetY + mg * gridVectorX - ng * gridVectorY) >> 8;
1097
- // Draw patternBitmap at (x, y).
1098
- if (
1099
- x >= 0 &&
1100
- x + patternWidth <= regionWidth &&
1101
- y >= 0 &&
1102
- y + patternHeight <= regionHeight
1103
- ) {
1104
- for (i = 0; i < patternHeight; i++) {
1105
- regionRow = regionBitmap[y + i];
1106
- patternRow = patternBitmap[i];
1107
- for (j = 0; j < patternWidth; j++) {
1108
- regionRow[x + j] |= patternRow[j];
1109
- }
1110
- }
1111
- } else {
1112
- let regionX, regionY;
1113
- for (i = 0; i < patternHeight; i++) {
1114
- regionY = y + i;
1115
- if (regionY < 0 || regionY >= regionHeight) {
1116
- continue;
1117
- }
1118
- regionRow = regionBitmap[regionY];
1119
- patternRow = patternBitmap[i];
1120
- for (j = 0; j < patternWidth; j++) {
1121
- regionX = x + j;
1122
- if (regionX >= 0 && regionX < regionWidth) {
1123
- regionRow[regionX] |= patternRow[j];
1124
- }
1125
- }
1126
- }
1127
- }
1128
- }
1129
- }
1130
- return regionBitmap;
1131
- }
1132
-
1133
- function readSegmentHeader(data, start) {
1134
- const segmentHeader = {};
1135
- segmentHeader.number = readUint32(data, start);
1136
- const flags = data[start + 4];
1137
- const segmentType = flags & 0x3f;
1138
- if (!SegmentTypes[segmentType]) {
1139
- throw new Jbig2Error("invalid segment type: " + segmentType);
1140
- }
1141
- segmentHeader.type = segmentType;
1142
- segmentHeader.typeName = SegmentTypes[segmentType];
1143
- segmentHeader.deferredNonRetain = !!(flags & 0x80);
1144
-
1145
- const pageAssociationFieldSize = !!(flags & 0x40);
1146
- const referredFlags = data[start + 5];
1147
- let referredToCount = (referredFlags >> 5) & 7;
1148
- const retainBits = [referredFlags & 31];
1149
- let position = start + 6;
1150
- if (referredFlags === 7) {
1151
- referredToCount = readUint32(data, position - 1) & 0x1fffffff;
1152
- position += 3;
1153
- let bytes = (referredToCount + 7) >> 3;
1154
- retainBits[0] = data[position++];
1155
- while (--bytes > 0) {
1156
- retainBits.push(data[position++]);
1157
- }
1158
- } else if (referredFlags === 5 || referredFlags === 6) {
1159
- throw new Jbig2Error("invalid referred-to flags");
1160
- }
1161
-
1162
- segmentHeader.retainBits = retainBits;
1163
-
1164
- let referredToSegmentNumberSize = 4;
1165
- if (segmentHeader.number <= 256) {
1166
- referredToSegmentNumberSize = 1;
1167
- } else if (segmentHeader.number <= 65536) {
1168
- referredToSegmentNumberSize = 2;
1169
- }
1170
- const referredTo = [];
1171
- let i, ii;
1172
- for (i = 0; i < referredToCount; i++) {
1173
- let number;
1174
- if (referredToSegmentNumberSize === 1) {
1175
- number = data[position];
1176
- } else if (referredToSegmentNumberSize === 2) {
1177
- number = readUint16(data, position);
1178
- } else {
1179
- number = readUint32(data, position);
1180
- }
1181
- referredTo.push(number);
1182
- position += referredToSegmentNumberSize;
1183
- }
1184
- segmentHeader.referredTo = referredTo;
1185
- if (!pageAssociationFieldSize) {
1186
- segmentHeader.pageAssociation = data[position++];
1187
- } else {
1188
- segmentHeader.pageAssociation = readUint32(data, position);
1189
- position += 4;
1190
- }
1191
- segmentHeader.length = readUint32(data, position);
1192
- position += 4;
1193
-
1194
- if (segmentHeader.length === 0xffffffff) {
1195
- // 7.2.7 Segment data length, unknown segment length
1196
- if (segmentType === 38) {
1197
- // ImmediateGenericRegion
1198
- const genericRegionInfo = readRegionSegmentInformation(data, position);
1199
- const genericRegionSegmentFlags =
1200
- data[position + RegionSegmentInformationFieldLength];
1201
- const genericRegionMmr = !!(genericRegionSegmentFlags & 1);
1202
- // searching for the segment end
1203
- const searchPatternLength = 6;
1204
- const searchPattern = new Uint8Array(searchPatternLength);
1205
- if (!genericRegionMmr) {
1206
- searchPattern[0] = 0xff;
1207
- searchPattern[1] = 0xac;
1208
- }
1209
- searchPattern[2] = (genericRegionInfo.height >>> 24) & 0xff;
1210
- searchPattern[3] = (genericRegionInfo.height >> 16) & 0xff;
1211
- searchPattern[4] = (genericRegionInfo.height >> 8) & 0xff;
1212
- searchPattern[5] = genericRegionInfo.height & 0xff;
1213
- for (i = position, ii = data.length; i < ii; i++) {
1214
- let j = 0;
1215
- while (j < searchPatternLength && searchPattern[j] === data[i + j]) {
1216
- j++;
1217
- }
1218
- if (j === searchPatternLength) {
1219
- segmentHeader.length = i + searchPatternLength;
1220
- break;
1221
- }
1222
- }
1223
- if (segmentHeader.length === 0xffffffff) {
1224
- throw new Jbig2Error("segment end was not found");
1225
- }
1226
- } else {
1227
- throw new Jbig2Error("invalid unknown segment length");
1228
- }
1229
- }
1230
- segmentHeader.headerEnd = position;
1231
- return segmentHeader;
1232
- }
1233
-
1234
- function readSegments(header, data, start, end) {
1235
- const segments = [];
1236
- let position = start;
1237
- while (position < end) {
1238
- const segmentHeader = readSegmentHeader(data, position);
1239
- position = segmentHeader.headerEnd;
1240
- const segment = {
1241
- header: segmentHeader,
1242
- data,
1243
- };
1244
- if (!header.randomAccess) {
1245
- segment.start = position;
1246
- position += segmentHeader.length;
1247
- segment.end = position;
1248
- }
1249
- segments.push(segment);
1250
- if (segmentHeader.type === 51) {
1251
- break; // end of file is found
1252
- }
1253
- }
1254
- if (header.randomAccess) {
1255
- for (let i = 0, ii = segments.length; i < ii; i++) {
1256
- segments[i].start = position;
1257
- position += segments[i].header.length;
1258
- segments[i].end = position;
1259
- }
1260
- }
1261
- return segments;
1262
- }
1263
-
1264
- // 7.4.1 Region segment information field
1265
- function readRegionSegmentInformation(data, start) {
1266
- return {
1267
- width: readUint32(data, start),
1268
- height: readUint32(data, start + 4),
1269
- x: readUint32(data, start + 8),
1270
- y: readUint32(data, start + 12),
1271
- combinationOperator: data[start + 16] & 7,
1272
- };
1273
- }
1274
- const RegionSegmentInformationFieldLength = 17;
1275
-
1276
- function processSegment(segment, visitor) {
1277
- const header = segment.header;
1278
-
1279
- const data = segment.data,
1280
- end = segment.end;
1281
- let position = segment.start;
1282
- let args, at, i, atLength;
1283
- switch (header.type) {
1284
- case 0: // SymbolDictionary
1285
- // 7.4.2 Symbol dictionary segment syntax
1286
- const dictionary = {};
1287
- const dictionaryFlags = readUint16(data, position); // 7.4.2.1.1
1288
- dictionary.huffman = !!(dictionaryFlags & 1);
1289
- dictionary.refinement = !!(dictionaryFlags & 2);
1290
- dictionary.huffmanDHSelector = (dictionaryFlags >> 2) & 3;
1291
- dictionary.huffmanDWSelector = (dictionaryFlags >> 4) & 3;
1292
- dictionary.bitmapSizeSelector = (dictionaryFlags >> 6) & 1;
1293
- dictionary.aggregationInstancesSelector = (dictionaryFlags >> 7) & 1;
1294
- dictionary.bitmapCodingContextUsed = !!(dictionaryFlags & 256);
1295
- dictionary.bitmapCodingContextRetained = !!(dictionaryFlags & 512);
1296
- dictionary.template = (dictionaryFlags >> 10) & 3;
1297
- dictionary.refinementTemplate = (dictionaryFlags >> 12) & 1;
1298
- position += 2;
1299
- if (!dictionary.huffman) {
1300
- atLength = dictionary.template === 0 ? 4 : 1;
1301
- at = [];
1302
- for (i = 0; i < atLength; i++) {
1303
- at.push({
1304
- x: readInt8(data, position),
1305
- y: readInt8(data, position + 1),
1306
- });
1307
- position += 2;
1308
- }
1309
- dictionary.at = at;
1310
- }
1311
- if (dictionary.refinement && !dictionary.refinementTemplate) {
1312
- at = [];
1313
- for (i = 0; i < 2; i++) {
1314
- at.push({
1315
- x: readInt8(data, position),
1316
- y: readInt8(data, position + 1),
1317
- });
1318
- position += 2;
1319
- }
1320
- dictionary.refinementAt = at;
1321
- }
1322
- dictionary.numberOfExportedSymbols = readUint32(data, position);
1323
- position += 4;
1324
- dictionary.numberOfNewSymbols = readUint32(data, position);
1325
- position += 4;
1326
- args = [
1327
- dictionary,
1328
- header.number,
1329
- header.referredTo,
1330
- data,
1331
- position,
1332
- end,
1333
- ];
1334
- break;
1335
- case 6: // ImmediateTextRegion
1336
- case 7: // ImmediateLosslessTextRegion
1337
- const textRegion = {};
1338
- textRegion.info = readRegionSegmentInformation(data, position);
1339
- position += RegionSegmentInformationFieldLength;
1340
- const textRegionSegmentFlags = readUint16(data, position);
1341
- position += 2;
1342
- textRegion.huffman = !!(textRegionSegmentFlags & 1);
1343
- textRegion.refinement = !!(textRegionSegmentFlags & 2);
1344
- textRegion.logStripSize = (textRegionSegmentFlags >> 2) & 3;
1345
- textRegion.stripSize = 1 << textRegion.logStripSize;
1346
- textRegion.referenceCorner = (textRegionSegmentFlags >> 4) & 3;
1347
- textRegion.transposed = !!(textRegionSegmentFlags & 64);
1348
- textRegion.combinationOperator = (textRegionSegmentFlags >> 7) & 3;
1349
- textRegion.defaultPixelValue = (textRegionSegmentFlags >> 9) & 1;
1350
- textRegion.dsOffset = (textRegionSegmentFlags << 17) >> 27;
1351
- textRegion.refinementTemplate = (textRegionSegmentFlags >> 15) & 1;
1352
- if (textRegion.huffman) {
1353
- const textRegionHuffmanFlags = readUint16(data, position);
1354
- position += 2;
1355
- textRegion.huffmanFS = textRegionHuffmanFlags & 3;
1356
- textRegion.huffmanDS = (textRegionHuffmanFlags >> 2) & 3;
1357
- textRegion.huffmanDT = (textRegionHuffmanFlags >> 4) & 3;
1358
- textRegion.huffmanRefinementDW = (textRegionHuffmanFlags >> 6) & 3;
1359
- textRegion.huffmanRefinementDH = (textRegionHuffmanFlags >> 8) & 3;
1360
- textRegion.huffmanRefinementDX = (textRegionHuffmanFlags >> 10) & 3;
1361
- textRegion.huffmanRefinementDY = (textRegionHuffmanFlags >> 12) & 3;
1362
- textRegion.huffmanRefinementSizeSelector = !!(
1363
- textRegionHuffmanFlags & 0x4000
1364
- );
1365
- }
1366
- if (textRegion.refinement && !textRegion.refinementTemplate) {
1367
- at = [];
1368
- for (i = 0; i < 2; i++) {
1369
- at.push({
1370
- x: readInt8(data, position),
1371
- y: readInt8(data, position + 1),
1372
- });
1373
- position += 2;
1374
- }
1375
- textRegion.refinementAt = at;
1376
- }
1377
- textRegion.numberOfSymbolInstances = readUint32(data, position);
1378
- position += 4;
1379
- args = [textRegion, header.referredTo, data, position, end];
1380
- break;
1381
- case 16: // PatternDictionary
1382
- // 7.4.4. Pattern dictionary segment syntax
1383
- const patternDictionary = {};
1384
- const patternDictionaryFlags = data[position++];
1385
- patternDictionary.mmr = !!(patternDictionaryFlags & 1);
1386
- patternDictionary.template = (patternDictionaryFlags >> 1) & 3;
1387
- patternDictionary.patternWidth = data[position++];
1388
- patternDictionary.patternHeight = data[position++];
1389
- patternDictionary.maxPatternIndex = readUint32(data, position);
1390
- position += 4;
1391
- args = [patternDictionary, header.number, data, position, end];
1392
- break;
1393
- case 22: // ImmediateHalftoneRegion
1394
- case 23: // ImmediateLosslessHalftoneRegion
1395
- // 7.4.5 Halftone region segment syntax
1396
- const halftoneRegion = {};
1397
- halftoneRegion.info = readRegionSegmentInformation(data, position);
1398
- position += RegionSegmentInformationFieldLength;
1399
- const halftoneRegionFlags = data[position++];
1400
- halftoneRegion.mmr = !!(halftoneRegionFlags & 1);
1401
- halftoneRegion.template = (halftoneRegionFlags >> 1) & 3;
1402
- halftoneRegion.enableSkip = !!(halftoneRegionFlags & 8);
1403
- halftoneRegion.combinationOperator = (halftoneRegionFlags >> 4) & 7;
1404
- halftoneRegion.defaultPixelValue = (halftoneRegionFlags >> 7) & 1;
1405
- halftoneRegion.gridWidth = readUint32(data, position);
1406
- position += 4;
1407
- halftoneRegion.gridHeight = readUint32(data, position);
1408
- position += 4;
1409
- halftoneRegion.gridOffsetX = readUint32(data, position) & 0xffffffff;
1410
- position += 4;
1411
- halftoneRegion.gridOffsetY = readUint32(data, position) & 0xffffffff;
1412
- position += 4;
1413
- halftoneRegion.gridVectorX = readUint16(data, position);
1414
- position += 2;
1415
- halftoneRegion.gridVectorY = readUint16(data, position);
1416
- position += 2;
1417
- args = [halftoneRegion, header.referredTo, data, position, end];
1418
- break;
1419
- case 38: // ImmediateGenericRegion
1420
- case 39: // ImmediateLosslessGenericRegion
1421
- const genericRegion = {};
1422
- genericRegion.info = readRegionSegmentInformation(data, position);
1423
- position += RegionSegmentInformationFieldLength;
1424
- const genericRegionSegmentFlags = data[position++];
1425
- genericRegion.mmr = !!(genericRegionSegmentFlags & 1);
1426
- genericRegion.template = (genericRegionSegmentFlags >> 1) & 3;
1427
- genericRegion.prediction = !!(genericRegionSegmentFlags & 8);
1428
- if (!genericRegion.mmr) {
1429
- atLength = genericRegion.template === 0 ? 4 : 1;
1430
- at = [];
1431
- for (i = 0; i < atLength; i++) {
1432
- at.push({
1433
- x: readInt8(data, position),
1434
- y: readInt8(data, position + 1),
1435
- });
1436
- position += 2;
1437
- }
1438
- genericRegion.at = at;
1439
- }
1440
- args = [genericRegion, data, position, end];
1441
- break;
1442
- case 48: // PageInformation
1443
- const pageInfo = {
1444
- width: readUint32(data, position),
1445
- height: readUint32(data, position + 4),
1446
- resolutionX: readUint32(data, position + 8),
1447
- resolutionY: readUint32(data, position + 12),
1448
- };
1449
- if (pageInfo.height === 0xffffffff) {
1450
- delete pageInfo.height;
1451
- }
1452
- const pageSegmentFlags = data[position + 16];
1453
- readUint16(data, position + 17); // pageStripingInformation
1454
- pageInfo.lossless = !!(pageSegmentFlags & 1);
1455
- pageInfo.refinement = !!(pageSegmentFlags & 2);
1456
- pageInfo.defaultPixelValue = (pageSegmentFlags >> 2) & 1;
1457
- pageInfo.combinationOperator = (pageSegmentFlags >> 3) & 3;
1458
- pageInfo.requiresBuffer = !!(pageSegmentFlags & 32);
1459
- pageInfo.combinationOperatorOverride = !!(pageSegmentFlags & 64);
1460
- args = [pageInfo];
1461
- break;
1462
- case 49: // EndOfPage
1463
- break;
1464
- case 50: // EndOfStripe
1465
- break;
1466
- case 51: // EndOfFile
1467
- break;
1468
- case 53: // Tables
1469
- args = [header.number, data, position, end];
1470
- break;
1471
- case 62: // 7.4.15 defines 2 extension types which
1472
- // are comments and can be ignored.
1473
- break;
1474
- default:
1475
- throw new Jbig2Error(
1476
- `segment type ${header.typeName}(${header.type})` +
1477
- " is not implemented"
1478
- );
1479
- }
1480
- const callbackName = "on" + header.typeName;
1481
- if (callbackName in visitor) {
1482
- visitor[callbackName].apply(visitor, args);
1483
- }
1484
- }
1485
-
1486
- function processSegments(segments, visitor) {
1487
- for (let i = 0, ii = segments.length; i < ii; i++) {
1488
- processSegment(segments[i], visitor);
1489
- }
1490
- }
1491
-
1492
- function parseJbig2Chunks(chunks) {
1493
- const visitor = new SimpleSegmentVisitor();
1494
- for (let i = 0, ii = chunks.length; i < ii; i++) {
1495
- const chunk = chunks[i];
1496
- const segments = readSegments({}, chunk.data, chunk.start, chunk.end);
1497
- processSegments(segments, visitor);
1498
- }
1499
- return visitor.buffer;
1500
- }
1501
-
1502
- function parseJbig2(data) {
1503
- const end = data.length;
1504
- let position = 0;
1505
-
1506
- if (
1507
- data[position] !== 0x97 ||
1508
- data[position + 1] !== 0x4a ||
1509
- data[position + 2] !== 0x42 ||
1510
- data[position + 3] !== 0x32 ||
1511
- data[position + 4] !== 0x0d ||
1512
- data[position + 5] !== 0x0a ||
1513
- data[position + 6] !== 0x1a ||
1514
- data[position + 7] !== 0x0a
1515
- ) {
1516
- throw new Jbig2Error("parseJbig2 - invalid header.");
1517
- }
1518
-
1519
- const header = Object.create(null);
1520
- position += 8;
1521
- const flags = data[position++];
1522
- header.randomAccess = !(flags & 1);
1523
- if (!(flags & 2)) {
1524
- header.numberOfPages = readUint32(data, position);
1525
- position += 4;
1526
- }
1527
-
1528
- const segments = readSegments(header, data, position, end);
1529
- const visitor = new SimpleSegmentVisitor();
1530
- processSegments(segments, visitor);
1531
-
1532
- const { width, height } = visitor.currentPageInfo;
1533
- const bitPacked = visitor.buffer;
1534
- const imgData = new Uint8ClampedArray(width * height);
1535
- let q = 0,
1536
- k = 0;
1537
- for (let i = 0; i < height; i++) {
1538
- let mask = 0,
1539
- buffer;
1540
- for (let j = 0; j < width; j++) {
1541
- if (!mask) {
1542
- mask = 128;
1543
- buffer = bitPacked[k++];
1544
- }
1545
- imgData[q++] = buffer & mask ? 0 : 255;
1546
- mask >>= 1;
1547
- }
1548
- }
1549
-
1550
- return { imgData, width, height };
1551
- }
1552
-
1553
- class SimpleSegmentVisitor {
1554
- onPageInformation(info) {
1555
- this.currentPageInfo = info;
1556
- const rowSize = (info.width + 7) >> 3;
1557
- const buffer = new Uint8ClampedArray(rowSize * info.height);
1558
- // The contents of ArrayBuffers are initialized to 0.
1559
- // Fill the buffer with 0xFF only if info.defaultPixelValue is set
1560
- if (info.defaultPixelValue) {
1561
- for (let i = 0, ii = buffer.length; i < ii; i++) {
1562
- buffer[i] = 0xff;
1563
- }
1564
- }
1565
- this.buffer = buffer;
1566
- }
1567
-
1568
- drawBitmap(regionInfo, bitmap) {
1569
- const pageInfo = this.currentPageInfo;
1570
- const width = regionInfo.width,
1571
- height = regionInfo.height;
1572
- const rowSize = (pageInfo.width + 7) >> 3;
1573
- const combinationOperator = pageInfo.combinationOperatorOverride
1574
- ? regionInfo.combinationOperator
1575
- : pageInfo.combinationOperator;
1576
- const buffer = this.buffer;
1577
- const mask0 = 128 >> (regionInfo.x & 7);
1578
- let offset0 = regionInfo.y * rowSize + (regionInfo.x >> 3);
1579
- let i, j, mask, offset;
1580
- switch (combinationOperator) {
1581
- case 0: // OR
1582
- for (i = 0; i < height; i++) {
1583
- mask = mask0;
1584
- offset = offset0;
1585
- for (j = 0; j < width; j++) {
1586
- if (bitmap[i][j]) {
1587
- buffer[offset] |= mask;
1588
- }
1589
- mask >>= 1;
1590
- if (!mask) {
1591
- mask = 128;
1592
- offset++;
1593
- }
1594
- }
1595
- offset0 += rowSize;
1596
- }
1597
- break;
1598
- case 2: // XOR
1599
- for (i = 0; i < height; i++) {
1600
- mask = mask0;
1601
- offset = offset0;
1602
- for (j = 0; j < width; j++) {
1603
- if (bitmap[i][j]) {
1604
- buffer[offset] ^= mask;
1605
- }
1606
- mask >>= 1;
1607
- if (!mask) {
1608
- mask = 128;
1609
- offset++;
1610
- }
1611
- }
1612
- offset0 += rowSize;
1613
- }
1614
- break;
1615
- default:
1616
- throw new Jbig2Error(
1617
- `operator ${combinationOperator} is not supported`
1618
- );
1619
- }
1620
- }
1621
-
1622
- onImmediateGenericRegion(region, data, start, end) {
1623
- const regionInfo = region.info;
1624
- const decodingContext = new DecodingContext(data, start, end);
1625
- const bitmap = decodeBitmap(
1626
- region.mmr,
1627
- regionInfo.width,
1628
- regionInfo.height,
1629
- region.template,
1630
- region.prediction,
1631
- null,
1632
- region.at,
1633
- decodingContext
1634
- );
1635
- this.drawBitmap(regionInfo, bitmap);
1636
- }
1637
-
1638
- onImmediateLosslessGenericRegion() {
1639
- this.onImmediateGenericRegion.apply(this, arguments);
1640
- }
1641
-
1642
- onSymbolDictionary(
1643
- dictionary,
1644
- currentSegment,
1645
- referredSegments,
1646
- data,
1647
- start,
1648
- end
1649
- ) {
1650
- let huffmanTables, huffmanInput;
1651
- if (dictionary.huffman) {
1652
- huffmanTables = getSymbolDictionaryHuffmanTables(
1653
- dictionary,
1654
- referredSegments,
1655
- this.customTables
1656
- );
1657
- huffmanInput = new Reader(data, start, end);
1658
- }
1659
-
1660
- // Combines exported symbols from all referred segments
1661
- let symbols = this.symbols;
1662
- if (!symbols) {
1663
- this.symbols = symbols = {};
1664
- }
1665
-
1666
- let inputSymbols = [];
1667
- for (let i = 0, ii = referredSegments.length; i < ii; i++) {
1668
- const referredSymbols = symbols[referredSegments[i]];
1669
- // referredSymbols is undefined when we have a reference to a Tables
1670
- // segment instead of a SymbolDictionary.
1671
- if (referredSymbols) {
1672
- inputSymbols = inputSymbols.concat(referredSymbols);
1673
- }
1674
- }
1675
-
1676
- const decodingContext = new DecodingContext(data, start, end);
1677
- symbols[currentSegment] = decodeSymbolDictionary(
1678
- dictionary.huffman,
1679
- dictionary.refinement,
1680
- inputSymbols,
1681
- dictionary.numberOfNewSymbols,
1682
- dictionary.numberOfExportedSymbols,
1683
- huffmanTables,
1684
- dictionary.template,
1685
- dictionary.at,
1686
- dictionary.refinementTemplate,
1687
- dictionary.refinementAt,
1688
- decodingContext,
1689
- huffmanInput
1690
- );
1691
- }
1692
-
1693
- onImmediateTextRegion(region, referredSegments, data, start, end) {
1694
- const regionInfo = region.info;
1695
- let huffmanTables, huffmanInput;
1696
-
1697
- // Combines exported symbols from all referred segments
1698
- const symbols = this.symbols;
1699
- let inputSymbols = [];
1700
- for (let i = 0, ii = referredSegments.length; i < ii; i++) {
1701
- const referredSymbols = symbols[referredSegments[i]];
1702
- // referredSymbols is undefined when we have a reference to a Tables
1703
- // segment instead of a SymbolDictionary.
1704
- if (referredSymbols) {
1705
- inputSymbols = inputSymbols.concat(referredSymbols);
1706
- }
1707
- }
1708
- const symbolCodeLength = log2(inputSymbols.length);
1709
- if (region.huffman) {
1710
- huffmanInput = new Reader(data, start, end);
1711
- huffmanTables = getTextRegionHuffmanTables(
1712
- region,
1713
- referredSegments,
1714
- this.customTables,
1715
- inputSymbols.length,
1716
- huffmanInput
1717
- );
1718
- }
1719
-
1720
- const decodingContext = new DecodingContext(data, start, end);
1721
- const bitmap = decodeTextRegion(
1722
- region.huffman,
1723
- region.refinement,
1724
- regionInfo.width,
1725
- regionInfo.height,
1726
- region.defaultPixelValue,
1727
- region.numberOfSymbolInstances,
1728
- region.stripSize,
1729
- inputSymbols,
1730
- symbolCodeLength,
1731
- region.transposed,
1732
- region.dsOffset,
1733
- region.referenceCorner,
1734
- region.combinationOperator,
1735
- huffmanTables,
1736
- region.refinementTemplate,
1737
- region.refinementAt,
1738
- decodingContext,
1739
- region.logStripSize,
1740
- huffmanInput
1741
- );
1742
- this.drawBitmap(regionInfo, bitmap);
1743
- }
1744
-
1745
- onImmediateLosslessTextRegion() {
1746
- this.onImmediateTextRegion.apply(this, arguments);
1747
- }
1748
-
1749
- onPatternDictionary(dictionary, currentSegment, data, start, end) {
1750
- let patterns = this.patterns;
1751
- if (!patterns) {
1752
- this.patterns = patterns = {};
1753
- }
1754
- const decodingContext = new DecodingContext(data, start, end);
1755
- patterns[currentSegment] = decodePatternDictionary(
1756
- dictionary.mmr,
1757
- dictionary.patternWidth,
1758
- dictionary.patternHeight,
1759
- dictionary.maxPatternIndex,
1760
- dictionary.template,
1761
- decodingContext
1762
- );
1763
- }
1764
-
1765
- onImmediateHalftoneRegion(region, referredSegments, data, start, end) {
1766
- // HalftoneRegion refers to exactly one PatternDictionary.
1767
- const patterns = this.patterns[referredSegments[0]];
1768
- const regionInfo = region.info;
1769
- const decodingContext = new DecodingContext(data, start, end);
1770
- const bitmap = decodeHalftoneRegion(
1771
- region.mmr,
1772
- patterns,
1773
- region.template,
1774
- regionInfo.width,
1775
- regionInfo.height,
1776
- region.defaultPixelValue,
1777
- region.enableSkip,
1778
- region.combinationOperator,
1779
- region.gridWidth,
1780
- region.gridHeight,
1781
- region.gridOffsetX,
1782
- region.gridOffsetY,
1783
- region.gridVectorX,
1784
- region.gridVectorY,
1785
- decodingContext
1786
- );
1787
- this.drawBitmap(regionInfo, bitmap);
1788
- }
1789
-
1790
- onImmediateLosslessHalftoneRegion() {
1791
- this.onImmediateHalftoneRegion.apply(this, arguments);
1792
- }
1793
-
1794
- onTables(currentSegment, data, start, end) {
1795
- let customTables = this.customTables;
1796
- if (!customTables) {
1797
- this.customTables = customTables = {};
1798
- }
1799
- customTables[currentSegment] = decodeTablesSegment(data, start, end);
1800
- }
1801
- }
1802
-
1803
- class HuffmanLine {
1804
- constructor(lineData) {
1805
- if (lineData.length === 2) {
1806
- // OOB line.
1807
- this.isOOB = true;
1808
- this.rangeLow = 0;
1809
- this.prefixLength = lineData[0];
1810
- this.rangeLength = 0;
1811
- this.prefixCode = lineData[1];
1812
- this.isLowerRange = false;
1813
- } else {
1814
- // Normal, upper range or lower range line.
1815
- // Upper range lines are processed like normal lines.
1816
- this.isOOB = false;
1817
- this.rangeLow = lineData[0];
1818
- this.prefixLength = lineData[1];
1819
- this.rangeLength = lineData[2];
1820
- this.prefixCode = lineData[3];
1821
- this.isLowerRange = lineData[4] === "lower";
1822
- }
1823
- }
1824
- }
1825
-
1826
- class HuffmanTreeNode {
1827
- constructor(line) {
1828
- this.children = [];
1829
- if (line) {
1830
- // Leaf node
1831
- this.isLeaf = true;
1832
- this.rangeLength = line.rangeLength;
1833
- this.rangeLow = line.rangeLow;
1834
- this.isLowerRange = line.isLowerRange;
1835
- this.isOOB = line.isOOB;
1836
- } else {
1837
- // Intermediate or root node
1838
- this.isLeaf = false;
1839
- }
1840
- }
1841
-
1842
- buildTree(line, shift) {
1843
- const bit = (line.prefixCode >> shift) & 1;
1844
- if (shift <= 0) {
1845
- // Create a leaf node.
1846
- this.children[bit] = new HuffmanTreeNode(line);
1847
- } else {
1848
- // Create an intermediate node and continue recursively.
1849
- let node = this.children[bit];
1850
- if (!node) {
1851
- this.children[bit] = node = new HuffmanTreeNode(null);
1852
- }
1853
- node.buildTree(line, shift - 1);
1854
- }
1855
- }
1856
-
1857
- decodeNode(reader) {
1858
- if (this.isLeaf) {
1859
- if (this.isOOB) {
1860
- return null;
1861
- }
1862
- const htOffset = reader.readBits(this.rangeLength);
1863
- return this.rangeLow + (this.isLowerRange ? -htOffset : htOffset);
1864
- }
1865
- const node = this.children[reader.readBit()];
1866
- if (!node) {
1867
- throw new Jbig2Error("invalid Huffman data");
1868
- }
1869
- return node.decodeNode(reader);
1870
- }
1871
- }
1872
-
1873
- class HuffmanTable {
1874
- constructor(lines, prefixCodesDone) {
1875
- if (!prefixCodesDone) {
1876
- this.assignPrefixCodes(lines);
1877
- }
1878
- // Create Huffman tree.
1879
- this.rootNode = new HuffmanTreeNode(null);
1880
- for (let i = 0, ii = lines.length; i < ii; i++) {
1881
- const line = lines[i];
1882
- if (line.prefixLength > 0) {
1883
- this.rootNode.buildTree(line, line.prefixLength - 1);
1884
- }
1885
- }
1886
- }
1887
-
1888
- decode(reader) {
1889
- return this.rootNode.decodeNode(reader);
1890
- }
1891
-
1892
- assignPrefixCodes(lines) {
1893
- // Annex B.3 Assigning the prefix codes.
1894
- const linesLength = lines.length;
1895
- let prefixLengthMax = 0;
1896
- for (let i = 0; i < linesLength; i++) {
1897
- prefixLengthMax = Math.max(prefixLengthMax, lines[i].prefixLength);
1898
- }
1899
-
1900
- const histogram = new Uint32Array(prefixLengthMax + 1);
1901
- for (let i = 0; i < linesLength; i++) {
1902
- histogram[lines[i].prefixLength]++;
1903
- }
1904
- let currentLength = 1,
1905
- firstCode = 0,
1906
- currentCode,
1907
- currentTemp,
1908
- line;
1909
- histogram[0] = 0;
1910
-
1911
- while (currentLength <= prefixLengthMax) {
1912
- firstCode = (firstCode + histogram[currentLength - 1]) << 1;
1913
- currentCode = firstCode;
1914
- currentTemp = 0;
1915
- while (currentTemp < linesLength) {
1916
- line = lines[currentTemp];
1917
- if (line.prefixLength === currentLength) {
1918
- line.prefixCode = currentCode;
1919
- currentCode++;
1920
- }
1921
- currentTemp++;
1922
- }
1923
- currentLength++;
1924
- }
1925
- }
1926
- }
1927
-
1928
- function decodeTablesSegment(data, start, end) {
1929
- // Decodes a Tables segment, i.e., a custom Huffman table.
1930
- // Annex B.2 Code table structure.
1931
- const flags = data[start];
1932
- const lowestValue = readUint32(data, start + 1) & 0xffffffff;
1933
- const highestValue = readUint32(data, start + 5) & 0xffffffff;
1934
- const reader = new Reader(data, start + 9, end);
1935
-
1936
- const prefixSizeBits = ((flags >> 1) & 7) + 1;
1937
- const rangeSizeBits = ((flags >> 4) & 7) + 1;
1938
- const lines = [];
1939
- let prefixLength,
1940
- rangeLength,
1941
- currentRangeLow = lowestValue;
1942
-
1943
- // Normal table lines
1944
- do {
1945
- prefixLength = reader.readBits(prefixSizeBits);
1946
- rangeLength = reader.readBits(rangeSizeBits);
1947
- lines.push(
1948
- new HuffmanLine([currentRangeLow, prefixLength, rangeLength, 0])
1949
- );
1950
- currentRangeLow += 1 << rangeLength;
1951
- } while (currentRangeLow < highestValue);
1952
-
1953
- // Lower range table line
1954
- prefixLength = reader.readBits(prefixSizeBits);
1955
- lines.push(new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"]));
1956
-
1957
- // Upper range table line
1958
- prefixLength = reader.readBits(prefixSizeBits);
1959
- lines.push(new HuffmanLine([highestValue, prefixLength, 32, 0]));
1960
-
1961
- if (flags & 1) {
1962
- // Out-of-band table line
1963
- prefixLength = reader.readBits(prefixSizeBits);
1964
- lines.push(new HuffmanLine([prefixLength, 0]));
1965
- }
1966
-
1967
- return new HuffmanTable(lines, false);
1968
- }
1969
-
1970
- const standardTablesCache = {};
1971
-
1972
- function getStandardTable(number) {
1973
- // Annex B.5 Standard Huffman tables.
1974
- let table = standardTablesCache[number];
1975
- if (table) {
1976
- return table;
1977
- }
1978
- let lines;
1979
- switch (number) {
1980
- case 1:
1981
- lines = [
1982
- [0, 1, 4, 0x0],
1983
- [16, 2, 8, 0x2],
1984
- [272, 3, 16, 0x6],
1985
- [65808, 3, 32, 0x7], // upper
1986
- ];
1987
- break;
1988
- case 2:
1989
- lines = [
1990
- [0, 1, 0, 0x0],
1991
- [1, 2, 0, 0x2],
1992
- [2, 3, 0, 0x6],
1993
- [3, 4, 3, 0xe],
1994
- [11, 5, 6, 0x1e],
1995
- [75, 6, 32, 0x3e], // upper
1996
- [6, 0x3f], // OOB
1997
- ];
1998
- break;
1999
- case 3:
2000
- lines = [
2001
- [-256, 8, 8, 0xfe],
2002
- [0, 1, 0, 0x0],
2003
- [1, 2, 0, 0x2],
2004
- [2, 3, 0, 0x6],
2005
- [3, 4, 3, 0xe],
2006
- [11, 5, 6, 0x1e],
2007
- [-257, 8, 32, 0xff, "lower"],
2008
- [75, 7, 32, 0x7e], // upper
2009
- [6, 0x3e], // OOB
2010
- ];
2011
- break;
2012
- case 4:
2013
- lines = [
2014
- [1, 1, 0, 0x0],
2015
- [2, 2, 0, 0x2],
2016
- [3, 3, 0, 0x6],
2017
- [4, 4, 3, 0xe],
2018
- [12, 5, 6, 0x1e],
2019
- [76, 5, 32, 0x1f], // upper
2020
- ];
2021
- break;
2022
- case 5:
2023
- lines = [
2024
- [-255, 7, 8, 0x7e],
2025
- [1, 1, 0, 0x0],
2026
- [2, 2, 0, 0x2],
2027
- [3, 3, 0, 0x6],
2028
- [4, 4, 3, 0xe],
2029
- [12, 5, 6, 0x1e],
2030
- [-256, 7, 32, 0x7f, "lower"],
2031
- [76, 6, 32, 0x3e], // upper
2032
- ];
2033
- break;
2034
- case 6:
2035
- lines = [
2036
- [-2048, 5, 10, 0x1c],
2037
- [-1024, 4, 9, 0x8],
2038
- [-512, 4, 8, 0x9],
2039
- [-256, 4, 7, 0xa],
2040
- [-128, 5, 6, 0x1d],
2041
- [-64, 5, 5, 0x1e],
2042
- [-32, 4, 5, 0xb],
2043
- [0, 2, 7, 0x0],
2044
- [128, 3, 7, 0x2],
2045
- [256, 3, 8, 0x3],
2046
- [512, 4, 9, 0xc],
2047
- [1024, 4, 10, 0xd],
2048
- [-2049, 6, 32, 0x3e, "lower"],
2049
- [2048, 6, 32, 0x3f], // upper
2050
- ];
2051
- break;
2052
- case 7:
2053
- lines = [
2054
- [-1024, 4, 9, 0x8],
2055
- [-512, 3, 8, 0x0],
2056
- [-256, 4, 7, 0x9],
2057
- [-128, 5, 6, 0x1a],
2058
- [-64, 5, 5, 0x1b],
2059
- [-32, 4, 5, 0xa],
2060
- [0, 4, 5, 0xb],
2061
- [32, 5, 5, 0x1c],
2062
- [64, 5, 6, 0x1d],
2063
- [128, 4, 7, 0xc],
2064
- [256, 3, 8, 0x1],
2065
- [512, 3, 9, 0x2],
2066
- [1024, 3, 10, 0x3],
2067
- [-1025, 5, 32, 0x1e, "lower"],
2068
- [2048, 5, 32, 0x1f], // upper
2069
- ];
2070
- break;
2071
- case 8:
2072
- lines = [
2073
- [-15, 8, 3, 0xfc],
2074
- [-7, 9, 1, 0x1fc],
2075
- [-5, 8, 1, 0xfd],
2076
- [-3, 9, 0, 0x1fd],
2077
- [-2, 7, 0, 0x7c],
2078
- [-1, 4, 0, 0xa],
2079
- [0, 2, 1, 0x0],
2080
- [2, 5, 0, 0x1a],
2081
- [3, 6, 0, 0x3a],
2082
- [4, 3, 4, 0x4],
2083
- [20, 6, 1, 0x3b],
2084
- [22, 4, 4, 0xb],
2085
- [38, 4, 5, 0xc],
2086
- [70, 5, 6, 0x1b],
2087
- [134, 5, 7, 0x1c],
2088
- [262, 6, 7, 0x3c],
2089
- [390, 7, 8, 0x7d],
2090
- [646, 6, 10, 0x3d],
2091
- [-16, 9, 32, 0x1fe, "lower"],
2092
- [1670, 9, 32, 0x1ff], // upper
2093
- [2, 0x1], // OOB
2094
- ];
2095
- break;
2096
- case 9:
2097
- lines = [
2098
- [-31, 8, 4, 0xfc],
2099
- [-15, 9, 2, 0x1fc],
2100
- [-11, 8, 2, 0xfd],
2101
- [-7, 9, 1, 0x1fd],
2102
- [-5, 7, 1, 0x7c],
2103
- [-3, 4, 1, 0xa],
2104
- [-1, 3, 1, 0x2],
2105
- [1, 3, 1, 0x3],
2106
- [3, 5, 1, 0x1a],
2107
- [5, 6, 1, 0x3a],
2108
- [7, 3, 5, 0x4],
2109
- [39, 6, 2, 0x3b],
2110
- [43, 4, 5, 0xb],
2111
- [75, 4, 6, 0xc],
2112
- [139, 5, 7, 0x1b],
2113
- [267, 5, 8, 0x1c],
2114
- [523, 6, 8, 0x3c],
2115
- [779, 7, 9, 0x7d],
2116
- [1291, 6, 11, 0x3d],
2117
- [-32, 9, 32, 0x1fe, "lower"],
2118
- [3339, 9, 32, 0x1ff], // upper
2119
- [2, 0x0], // OOB
2120
- ];
2121
- break;
2122
- case 10:
2123
- lines = [
2124
- [-21, 7, 4, 0x7a],
2125
- [-5, 8, 0, 0xfc],
2126
- [-4, 7, 0, 0x7b],
2127
- [-3, 5, 0, 0x18],
2128
- [-2, 2, 2, 0x0],
2129
- [2, 5, 0, 0x19],
2130
- [3, 6, 0, 0x36],
2131
- [4, 7, 0, 0x7c],
2132
- [5, 8, 0, 0xfd],
2133
- [6, 2, 6, 0x1],
2134
- [70, 5, 5, 0x1a],
2135
- [102, 6, 5, 0x37],
2136
- [134, 6, 6, 0x38],
2137
- [198, 6, 7, 0x39],
2138
- [326, 6, 8, 0x3a],
2139
- [582, 6, 9, 0x3b],
2140
- [1094, 6, 10, 0x3c],
2141
- [2118, 7, 11, 0x7d],
2142
- [-22, 8, 32, 0xfe, "lower"],
2143
- [4166, 8, 32, 0xff], // upper
2144
- [2, 0x2], // OOB
2145
- ];
2146
- break;
2147
- case 11:
2148
- lines = [
2149
- [1, 1, 0, 0x0],
2150
- [2, 2, 1, 0x2],
2151
- [4, 4, 0, 0xc],
2152
- [5, 4, 1, 0xd],
2153
- [7, 5, 1, 0x1c],
2154
- [9, 5, 2, 0x1d],
2155
- [13, 6, 2, 0x3c],
2156
- [17, 7, 2, 0x7a],
2157
- [21, 7, 3, 0x7b],
2158
- [29, 7, 4, 0x7c],
2159
- [45, 7, 5, 0x7d],
2160
- [77, 7, 6, 0x7e],
2161
- [141, 7, 32, 0x7f], // upper
2162
- ];
2163
- break;
2164
- case 12:
2165
- lines = [
2166
- [1, 1, 0, 0x0],
2167
- [2, 2, 0, 0x2],
2168
- [3, 3, 1, 0x6],
2169
- [5, 5, 0, 0x1c],
2170
- [6, 5, 1, 0x1d],
2171
- [8, 6, 1, 0x3c],
2172
- [10, 7, 0, 0x7a],
2173
- [11, 7, 1, 0x7b],
2174
- [13, 7, 2, 0x7c],
2175
- [17, 7, 3, 0x7d],
2176
- [25, 7, 4, 0x7e],
2177
- [41, 8, 5, 0xfe],
2178
- [73, 8, 32, 0xff], // upper
2179
- ];
2180
- break;
2181
- case 13:
2182
- lines = [
2183
- [1, 1, 0, 0x0],
2184
- [2, 3, 0, 0x4],
2185
- [3, 4, 0, 0xc],
2186
- [4, 5, 0, 0x1c],
2187
- [5, 4, 1, 0xd],
2188
- [7, 3, 3, 0x5],
2189
- [15, 6, 1, 0x3a],
2190
- [17, 6, 2, 0x3b],
2191
- [21, 6, 3, 0x3c],
2192
- [29, 6, 4, 0x3d],
2193
- [45, 6, 5, 0x3e],
2194
- [77, 7, 6, 0x7e],
2195
- [141, 7, 32, 0x7f], // upper
2196
- ];
2197
- break;
2198
- case 14:
2199
- lines = [
2200
- [-2, 3, 0, 0x4],
2201
- [-1, 3, 0, 0x5],
2202
- [0, 1, 0, 0x0],
2203
- [1, 3, 0, 0x6],
2204
- [2, 3, 0, 0x7],
2205
- ];
2206
- break;
2207
- case 15:
2208
- lines = [
2209
- [-24, 7, 4, 0x7c],
2210
- [-8, 6, 2, 0x3c],
2211
- [-4, 5, 1, 0x1c],
2212
- [-2, 4, 0, 0xc],
2213
- [-1, 3, 0, 0x4],
2214
- [0, 1, 0, 0x0],
2215
- [1, 3, 0, 0x5],
2216
- [2, 4, 0, 0xd],
2217
- [3, 5, 1, 0x1d],
2218
- [5, 6, 2, 0x3d],
2219
- [9, 7, 4, 0x7d],
2220
- [-25, 7, 32, 0x7e, "lower"],
2221
- [25, 7, 32, 0x7f], // upper
2222
- ];
2223
- break;
2224
- default:
2225
- throw new Jbig2Error(`standard table B.${number} does not exist`);
2226
- }
2227
-
2228
- for (let i = 0, ii = lines.length; i < ii; i++) {
2229
- lines[i] = new HuffmanLine(lines[i]);
2230
- }
2231
- table = new HuffmanTable(lines, true);
2232
- standardTablesCache[number] = table;
2233
- return table;
2234
- }
2235
-
2236
- class Reader {
2237
- constructor(data, start, end) {
2238
- this.data = data;
2239
- this.start = start;
2240
- this.end = end;
2241
- this.position = start;
2242
- this.shift = -1;
2243
- this.currentByte = 0;
2244
- }
2245
-
2246
- readBit() {
2247
- if (this.shift < 0) {
2248
- if (this.position >= this.end) {
2249
- throw new Jbig2Error("end of data while reading bit");
2250
- }
2251
- this.currentByte = this.data[this.position++];
2252
- this.shift = 7;
2253
- }
2254
- const bit = (this.currentByte >> this.shift) & 1;
2255
- this.shift--;
2256
- return bit;
2257
- }
2258
-
2259
- readBits(numBits) {
2260
- let result = 0,
2261
- i;
2262
- for (i = numBits - 1; i >= 0; i--) {
2263
- result |= this.readBit() << i;
2264
- }
2265
- return result;
2266
- }
2267
-
2268
- byteAlign() {
2269
- this.shift = -1;
2270
- }
2271
-
2272
- next() {
2273
- if (this.position >= this.end) {
2274
- return -1;
2275
- }
2276
- return this.data[this.position++];
2277
- }
2278
- }
2279
-
2280
- function getCustomHuffmanTable(index, referredTo, customTables) {
2281
- // Returns a Tables segment that has been earlier decoded.
2282
- // See 7.4.2.1.6 (symbol dictionary) or 7.4.3.1.6 (text region).
2283
- let currentIndex = 0;
2284
- for (let i = 0, ii = referredTo.length; i < ii; i++) {
2285
- const table = customTables[referredTo[i]];
2286
- if (table) {
2287
- if (index === currentIndex) {
2288
- return table;
2289
- }
2290
- currentIndex++;
2291
- }
2292
- }
2293
- throw new Jbig2Error("can't find custom Huffman table");
2294
- }
2295
-
2296
- function getTextRegionHuffmanTables(
2297
- textRegion,
2298
- referredTo,
2299
- customTables,
2300
- numberOfSymbols,
2301
- reader
2302
- ) {
2303
- // 7.4.3.1.7 Symbol ID Huffman table decoding
2304
-
2305
- // Read code lengths for RUNCODEs 0...34.
2306
- const codes = [];
2307
- for (let i = 0; i <= 34; i++) {
2308
- const codeLength = reader.readBits(4);
2309
- codes.push(new HuffmanLine([i, codeLength, 0, 0]));
2310
- }
2311
- // Assign Huffman codes for RUNCODEs.
2312
- const runCodesTable = new HuffmanTable(codes, false);
2313
-
2314
- // Read a Huffman code using the assignment above.
2315
- // Interpret the RUNCODE codes and the additional bits (if any).
2316
- codes.length = 0;
2317
- for (let i = 0; i < numberOfSymbols; ) {
2318
- const codeLength = runCodesTable.decode(reader);
2319
- if (codeLength >= 32) {
2320
- let repeatedLength, numberOfRepeats, j;
2321
- switch (codeLength) {
2322
- case 32:
2323
- if (i === 0) {
2324
- throw new Jbig2Error("no previous value in symbol ID table");
2325
- }
2326
- numberOfRepeats = reader.readBits(2) + 3;
2327
- repeatedLength = codes[i - 1].prefixLength;
2328
- break;
2329
- case 33:
2330
- numberOfRepeats = reader.readBits(3) + 3;
2331
- repeatedLength = 0;
2332
- break;
2333
- case 34:
2334
- numberOfRepeats = reader.readBits(7) + 11;
2335
- repeatedLength = 0;
2336
- break;
2337
- default:
2338
- throw new Jbig2Error("invalid code length in symbol ID table");
2339
- }
2340
- for (j = 0; j < numberOfRepeats; j++) {
2341
- codes.push(new HuffmanLine([i, repeatedLength, 0, 0]));
2342
- i++;
2343
- }
2344
- } else {
2345
- codes.push(new HuffmanLine([i, codeLength, 0, 0]));
2346
- i++;
2347
- }
2348
- }
2349
- reader.byteAlign();
2350
- const symbolIDTable = new HuffmanTable(codes, false);
2351
-
2352
- // 7.4.3.1.6 Text region segment Huffman table selection
2353
-
2354
- let customIndex = 0,
2355
- tableFirstS,
2356
- tableDeltaS,
2357
- tableDeltaT;
2358
-
2359
- switch (textRegion.huffmanFS) {
2360
- case 0:
2361
- case 1:
2362
- tableFirstS = getStandardTable(textRegion.huffmanFS + 6);
2363
- break;
2364
- case 3:
2365
- tableFirstS = getCustomHuffmanTable(
2366
- customIndex,
2367
- referredTo,
2368
- customTables
2369
- );
2370
- customIndex++;
2371
- break;
2372
- default:
2373
- throw new Jbig2Error("invalid Huffman FS selector");
2374
- }
2375
-
2376
- switch (textRegion.huffmanDS) {
2377
- case 0:
2378
- case 1:
2379
- case 2:
2380
- tableDeltaS = getStandardTable(textRegion.huffmanDS + 8);
2381
- break;
2382
- case 3:
2383
- tableDeltaS = getCustomHuffmanTable(
2384
- customIndex,
2385
- referredTo,
2386
- customTables
2387
- );
2388
- customIndex++;
2389
- break;
2390
- default:
2391
- throw new Jbig2Error("invalid Huffman DS selector");
2392
- }
2393
-
2394
- switch (textRegion.huffmanDT) {
2395
- case 0:
2396
- case 1:
2397
- case 2:
2398
- tableDeltaT = getStandardTable(textRegion.huffmanDT + 11);
2399
- break;
2400
- case 3:
2401
- tableDeltaT = getCustomHuffmanTable(
2402
- customIndex,
2403
- referredTo,
2404
- customTables
2405
- );
2406
- customIndex++;
2407
- break;
2408
- default:
2409
- throw new Jbig2Error("invalid Huffman DT selector");
2410
- }
2411
-
2412
- if (textRegion.refinement) {
2413
- // Load tables RDW, RDH, RDX and RDY.
2414
- throw new Jbig2Error("refinement with Huffman is not supported");
2415
- }
2416
-
2417
- return {
2418
- symbolIDTable,
2419
- tableFirstS,
2420
- tableDeltaS,
2421
- tableDeltaT,
2422
- };
2423
- }
2424
-
2425
- function getSymbolDictionaryHuffmanTables(
2426
- dictionary,
2427
- referredTo,
2428
- customTables
2429
- ) {
2430
- // 7.4.2.1.6 Symbol dictionary segment Huffman table selection
2431
-
2432
- let customIndex = 0,
2433
- tableDeltaHeight,
2434
- tableDeltaWidth;
2435
- switch (dictionary.huffmanDHSelector) {
2436
- case 0:
2437
- case 1:
2438
- tableDeltaHeight = getStandardTable(dictionary.huffmanDHSelector + 4);
2439
- break;
2440
- case 3:
2441
- tableDeltaHeight = getCustomHuffmanTable(
2442
- customIndex,
2443
- referredTo,
2444
- customTables
2445
- );
2446
- customIndex++;
2447
- break;
2448
- default:
2449
- throw new Jbig2Error("invalid Huffman DH selector");
2450
- }
2451
-
2452
- switch (dictionary.huffmanDWSelector) {
2453
- case 0:
2454
- case 1:
2455
- tableDeltaWidth = getStandardTable(dictionary.huffmanDWSelector + 2);
2456
- break;
2457
- case 3:
2458
- tableDeltaWidth = getCustomHuffmanTable(
2459
- customIndex,
2460
- referredTo,
2461
- customTables
2462
- );
2463
- customIndex++;
2464
- break;
2465
- default:
2466
- throw new Jbig2Error("invalid Huffman DW selector");
2467
- }
2468
-
2469
- let tableBitmapSize, tableAggregateInstances;
2470
- if (dictionary.bitmapSizeSelector) {
2471
- tableBitmapSize = getCustomHuffmanTable(
2472
- customIndex,
2473
- referredTo,
2474
- customTables
2475
- );
2476
- customIndex++;
2477
- } else {
2478
- tableBitmapSize = getStandardTable(1);
2479
- }
2480
-
2481
- if (dictionary.aggregationInstancesSelector) {
2482
- tableAggregateInstances = getCustomHuffmanTable(
2483
- customIndex,
2484
- referredTo,
2485
- customTables
2486
- );
2487
- } else {
2488
- tableAggregateInstances = getStandardTable(1);
2489
- }
2490
-
2491
- return {
2492
- tableDeltaHeight,
2493
- tableDeltaWidth,
2494
- tableBitmapSize,
2495
- tableAggregateInstances,
2496
- };
2497
- }
2498
-
2499
- function readUncompressedBitmap(reader, width, height) {
2500
- const bitmap = [];
2501
- for (let y = 0; y < height; y++) {
2502
- const row = new Uint8Array(width);
2503
- bitmap.push(row);
2504
- for (let x = 0; x < width; x++) {
2505
- row[x] = reader.readBit();
2506
- }
2507
- reader.byteAlign();
2508
- }
2509
- return bitmap;
2510
- }
2511
-
2512
- function decodeMMRBitmap(input, width, height, endOfBlock) {
2513
- // MMR is the same compression algorithm as the PDF filter
2514
- // CCITTFaxDecode with /K -1.
2515
- const params = {
2516
- K: -1,
2517
- Columns: width,
2518
- Rows: height,
2519
- BlackIs1: true,
2520
- EndOfBlock: endOfBlock,
2521
- };
2522
- const decoder = new CCITTFaxDecoder(input, params);
2523
- const bitmap = [];
2524
- let currentByte,
2525
- eof = false;
2526
-
2527
- for (let y = 0; y < height; y++) {
2528
- const row = new Uint8Array(width);
2529
- bitmap.push(row);
2530
- let shift = -1;
2531
- for (let x = 0; x < width; x++) {
2532
- if (shift < 0) {
2533
- currentByte = decoder.readNextChar();
2534
- if (currentByte === -1) {
2535
- // Set the rest of the bits to zero.
2536
- currentByte = 0;
2537
- eof = true;
2538
- }
2539
- shift = 7;
2540
- }
2541
- row[x] = (currentByte >> shift) & 1;
2542
- shift--;
2543
- }
2544
- }
2545
-
2546
- if (endOfBlock && !eof) {
2547
- // Read until EOFB has been consumed.
2548
- const lookForEOFLimit = 5;
2549
- for (let i = 0; i < lookForEOFLimit; i++) {
2550
- if (decoder.readNextChar() === -1) {
2551
- break;
2552
- }
2553
- }
2554
- }
2555
-
2556
- return bitmap;
2557
- }
2558
-
2559
- class Jbig2Image {
2560
- parseChunks(chunks) {
2561
- return parseJbig2Chunks(chunks);
2562
- }
2563
-
2564
- parse(data) {
2565
- const { imgData, width, height } = parseJbig2(data);
2566
- this.width = width;
2567
- this.height = height;
2568
- return imgData;
2569
- }
2570
- }
2571
-
2572
- export { Jbig2Image };