@file-viewer/core 2.0.11 → 2.1.1

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