pdf-parser.js 5.2.26 → 5.2.28

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 (221) hide show
  1. package/dist/{afm-widths-BYiX2L9D.cjs → afm-widths-BHD2HZIL.cjs} +553 -642
  2. package/dist/{afm-widths-blUDDjlI.js → afm-widths-B_IGbGky.js} +553 -642
  3. package/dist/afm-widths.cjs +1 -1
  4. package/dist/afm-widths.js +1 -1
  5. package/dist/annotations.cjs +5 -3
  6. package/dist/annotations.d.cts +2 -2
  7. package/dist/annotations.d.ts +2 -2
  8. package/dist/annotations.js +5 -3
  9. package/dist/attachments.d.cts +2 -2
  10. package/dist/attachments.d.ts +2 -2
  11. package/dist/builtin-encoding.cjs +17 -6
  12. package/dist/builtin-encoding.js +17 -6
  13. package/dist/bytes/crc32.cjs +5 -3
  14. package/dist/bytes/crc32.js +5 -3
  15. package/dist/bytes/flate.cjs +0 -1
  16. package/dist/bytes/flate.js +0 -1
  17. package/dist/cff-bounds.cjs +73 -45
  18. package/dist/cff-bounds.js +73 -45
  19. package/dist/cff.cjs +13 -6
  20. package/dist/cff.js +13 -6
  21. package/dist/cmap-table.cjs +54 -26
  22. package/dist/cmap-table.js +54 -26
  23. package/dist/cmap.cjs +5 -3
  24. package/dist/cmap.js +5 -3
  25. package/dist/content-read.d.cts +1 -1
  26. package/dist/content-read.d.ts +1 -1
  27. package/dist/content-write.cjs +21 -14
  28. package/dist/content-write.d.cts +2 -2
  29. package/dist/content-write.d.ts +2 -2
  30. package/dist/content-write.js +21 -14
  31. package/dist/crypto/aes.cjs +76 -55
  32. package/dist/crypto/aes.js +76 -55
  33. package/dist/crypto/md5.cjs +345 -149
  34. package/dist/crypto/md5.js +345 -149
  35. package/dist/crypto/rc4.cjs +5 -4
  36. package/dist/crypto/rc4.js +5 -4
  37. package/dist/crypto/sha2.cjs +92 -43
  38. package/dist/crypto/sha2.js +92 -43
  39. package/dist/document.cjs +17 -11
  40. package/dist/document.d.cts +1 -1
  41. package/dist/document.d.ts +1 -1
  42. package/dist/document.js +17 -11
  43. package/dist/{embedded-font-Bnhh4juV.d.ts → embedded-font-ByD7ZiQS.d.ts} +1 -1
  44. package/dist/{embedded-font-CEf-zBCA.d.cts → embedded-font-DgVBedw6.d.cts} +1 -1
  45. package/dist/embedded-font-write.d.cts +2 -2
  46. package/dist/embedded-font-write.d.ts +2 -2
  47. package/dist/embedded-font.cjs +4 -2
  48. package/dist/embedded-font.d.cts +1 -1
  49. package/dist/embedded-font.d.ts +1 -1
  50. package/dist/embedded-font.js +4 -2
  51. package/dist/encoding.cjs +1 -1
  52. package/dist/encoding.js +1 -1
  53. package/dist/encrypt-write.cjs +25 -21
  54. package/dist/encrypt-write.d.cts +1 -1
  55. package/dist/encrypt-write.d.ts +1 -1
  56. package/dist/encrypt-write.js +25 -21
  57. package/dist/encrypt.cjs +43 -64
  58. package/dist/encrypt.d.cts +1 -1
  59. package/dist/encrypt.d.ts +1 -1
  60. package/dist/encrypt.js +43 -64
  61. package/dist/filters.cjs +46 -26
  62. package/dist/filters.d.cts +1 -1
  63. package/dist/filters.d.ts +1 -1
  64. package/dist/filters.js +46 -26
  65. package/dist/font-face.cjs +2 -1
  66. package/dist/font-face.js +2 -1
  67. package/dist/font-read.cjs +12 -6
  68. package/dist/font-read.d.cts +1 -1
  69. package/dist/font-read.d.ts +1 -1
  70. package/dist/font-read.js +12 -6
  71. package/dist/font-registry.d.cts +3 -3
  72. package/dist/font-registry.d.ts +3 -3
  73. package/dist/font-tables.cjs +55 -28
  74. package/dist/font-tables.js +55 -28
  75. package/dist/form.cjs +13 -8
  76. package/dist/form.d.cts +2 -2
  77. package/dist/form.d.ts +2 -2
  78. package/dist/form.js +13 -8
  79. package/dist/gdef-table.cjs +6 -3
  80. package/dist/gdef-table.js +6 -3
  81. package/dist/{glyf-contours-C0epBNqP.d.ts → glyf-contours-B1PsI9oA.d.ts} +1 -1
  82. package/dist/{glyf-contours-BRpvd0rt.d.cts → glyf-contours-NHBpgks-.d.cts} +1 -1
  83. package/dist/glyf-contours.cjs +3 -1
  84. package/dist/glyf-contours.d.cts +1 -1
  85. package/dist/glyf-contours.d.ts +1 -1
  86. package/dist/glyf-contours.js +3 -1
  87. package/dist/glyf.cjs +22 -11
  88. package/dist/glyf.js +22 -11
  89. package/dist/gpos-table.cjs +37 -19
  90. package/dist/gpos-table.js +37 -19
  91. package/dist/gsub-table.cjs +40 -25
  92. package/dist/gsub-table.js +40 -25
  93. package/dist/hmtx-table.cjs +5 -3
  94. package/dist/hmtx-table.js +5 -3
  95. package/dist/image/ccitt-encode.cjs +8 -5
  96. package/dist/image/ccitt-encode.js +8 -5
  97. package/dist/image/ccitt.cjs +801 -209
  98. package/dist/image/ccitt.js +801 -209
  99. package/dist/image/jbig2-arith.cjs +340 -306
  100. package/dist/image/jbig2-arith.js +340 -306
  101. package/dist/image/jbig2-bitmap.cjs +8 -5
  102. package/dist/image/jbig2-bitmap.js +8 -5
  103. package/dist/image/jbig2-generic.cjs +240 -69
  104. package/dist/image/jbig2-generic.js +240 -69
  105. package/dist/image/jbig2-text.cjs +4 -2
  106. package/dist/image/jbig2-text.js +4 -2
  107. package/dist/image/jbig2.cjs +69 -31
  108. package/dist/image/jbig2.js +69 -31
  109. package/dist/image/jp2-boxes.cjs +52 -27
  110. package/dist/image/jp2-boxes.js +52 -27
  111. package/dist/image/jpeg-info.cjs +29 -24
  112. package/dist/image/jpeg-info.js +29 -24
  113. package/dist/image/jpeg2000-codestream.cjs +61 -32
  114. package/dist/image/jpeg2000-codestream.js +61 -32
  115. package/dist/image/jpeg2000-dwt.cjs +2 -1
  116. package/dist/image/jpeg2000-dwt.js +2 -1
  117. package/dist/image/jpeg2000-t1.cjs +21 -11
  118. package/dist/image/jpeg2000-t1.js +21 -11
  119. package/dist/image/jpeg2000-t2.cjs +12 -5
  120. package/dist/image/jpeg2000-t2.js +12 -5
  121. package/dist/image/jpeg2000-tagtree.cjs +8 -4
  122. package/dist/image/jpeg2000-tagtree.js +8 -4
  123. package/dist/image/jpeg2000.cjs +11 -6
  124. package/dist/image/jpeg2000.js +11 -6
  125. package/dist/image/png-decode.cjs +62 -39
  126. package/dist/image/png-decode.d.cts +3 -2
  127. package/dist/image/png-decode.d.ts +3 -2
  128. package/dist/image/png-decode.js +62 -39
  129. package/dist/image/png-filter.cjs +23 -15
  130. package/dist/image/png-filter.js +23 -15
  131. package/dist/images-read.cjs +41 -36
  132. package/dist/images-read.d.cts +2 -2
  133. package/dist/images-read.d.ts +2 -2
  134. package/dist/images-read.js +41 -36
  135. package/dist/index.cjs +1 -1
  136. package/dist/index.d.cts +1 -1
  137. package/dist/index.d.ts +1 -1
  138. package/dist/index.js +1 -1
  139. package/dist/interpret.cjs +68 -40
  140. package/dist/interpret.d.cts +1 -1
  141. package/dist/interpret.d.ts +1 -1
  142. package/dist/interpret.js +68 -40
  143. package/dist/lexer.cjs +86 -51
  144. package/dist/lexer.js +86 -51
  145. package/dist/math-content-write.cjs +9 -5
  146. package/dist/math-content-write.js +9 -5
  147. package/dist/math-font-write.cjs +2 -1
  148. package/dist/math-font-write.d.cts +1 -1
  149. package/dist/math-font-write.d.ts +1 -1
  150. package/dist/math-font-write.js +2 -1
  151. package/dist/math-font.cjs +16 -7
  152. package/dist/math-font.js +16 -7
  153. package/dist/math-table.cjs +25 -13
  154. package/dist/math-table.js +25 -13
  155. package/dist/matrix.cjs +3 -2
  156. package/dist/matrix.js +3 -2
  157. package/dist/measure.cjs +1 -1
  158. package/dist/measure.js +1 -1
  159. package/dist/names.cjs +7 -7
  160. package/dist/names.d.cts +2 -2
  161. package/dist/names.d.ts +2 -2
  162. package/dist/names.js +7 -7
  163. package/dist/navigation.cjs +16 -12
  164. package/dist/navigation.d.cts +4 -4
  165. package/dist/navigation.d.ts +4 -4
  166. package/dist/navigation.js +16 -12
  167. package/dist/{objects-B7HdMeWS.d.cts → objects-e2RS3-yT.d.cts} +3 -3
  168. package/dist/{objects-B7HdMeWS.d.ts → objects-e2RS3-yT.d.ts} +3 -3
  169. package/dist/objects.d.cts +1 -1
  170. package/dist/objects.d.ts +1 -1
  171. package/dist/optional-content.d.cts +2 -2
  172. package/dist/optional-content.d.ts +2 -2
  173. package/dist/ot-layout-common.cjs +22 -15
  174. package/dist/ot-layout-common.js +22 -15
  175. package/dist/parse.cjs +7 -5
  176. package/dist/parse.d.cts +1 -1
  177. package/dist/parse.d.ts +1 -1
  178. package/dist/parse.js +7 -5
  179. package/dist/pdf-text.cjs +5 -2
  180. package/dist/pdf-text.js +5 -2
  181. package/dist/predictors.cjs +14 -9
  182. package/dist/predictors.d.cts +1 -1
  183. package/dist/predictors.d.ts +1 -1
  184. package/dist/predictors.js +14 -9
  185. package/dist/raster.cjs +30 -19
  186. package/dist/raster.d.cts +8 -8
  187. package/dist/raster.d.ts +8 -8
  188. package/dist/raster.js +30 -19
  189. package/dist/read.cjs +29 -16
  190. package/dist/read.js +29 -16
  191. package/dist/serialize.cjs +6 -2
  192. package/dist/serialize.d.cts +1 -1
  193. package/dist/serialize.d.ts +1 -1
  194. package/dist/serialize.js +6 -2
  195. package/dist/sfnt-subset.cjs +25 -13
  196. package/dist/sfnt-subset.d.cts +1 -1
  197. package/dist/sfnt-subset.d.ts +1 -1
  198. package/dist/sfnt-subset.js +25 -13
  199. package/dist/sfnt.cjs +20 -10
  200. package/dist/sfnt.js +20 -10
  201. package/dist/structure.d.cts +2 -2
  202. package/dist/structure.d.ts +2 -2
  203. package/dist/text-group.cjs +0 -1
  204. package/dist/text-group.js +0 -1
  205. package/dist/text-layout.d.cts +1 -1
  206. package/dist/text-layout.d.ts +1 -1
  207. package/dist/tounicode.cjs +4 -2
  208. package/dist/tounicode.d.cts +1 -1
  209. package/dist/tounicode.d.ts +1 -1
  210. package/dist/tounicode.js +4 -2
  211. package/dist/winansi.cjs +1 -1
  212. package/dist/winansi.js +1 -1
  213. package/dist/write.cjs +20 -12
  214. package/dist/write.d.cts +1 -1
  215. package/dist/write.d.ts +1 -1
  216. package/dist/write.js +20 -12
  217. package/dist/xref.cjs +5 -2
  218. package/dist/xref.d.cts +1 -1
  219. package/dist/xref.d.ts +1 -1
  220. package/dist/xref.js +5 -2
  221. package/package.json +1 -1
@@ -15,6 +15,11 @@ const MARKER_COM = 65380;
15
15
  const MARKER_SOT = 65424;
16
16
  const MARKER_SOD = 65427;
17
17
  const MARKER_EOC = 65497;
18
+ const BITS_PER_BYTE = 8;
19
+ const HEX_RADIX = 16;
20
+ const NIBBLE_MASK = 15;
21
+ const NIBBLE_BITS = 4;
22
+ const UINT16_MODULUS = 65536;
18
23
  var MarkerCursor = class {
19
24
  data;
20
25
  position;
@@ -32,10 +37,10 @@ var MarkerCursor = class {
32
37
  return value;
33
38
  }
34
39
  uint16() {
35
- return this.uint8() << 8 | this.uint8();
40
+ return this.uint8() << BITS_PER_BYTE | this.uint8();
36
41
  }
37
42
  uint32() {
38
- return this.uint16() * 65536 + this.uint16();
43
+ return this.uint16() * UINT16_MODULUS + this.uint16();
39
44
  }
40
45
  bytes(length) {
41
46
  if (length < 0 || this.position + length > this.data.length) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("a JPEG 2000 marker segment declares more data than the codestream carries");
@@ -44,6 +49,9 @@ var MarkerCursor = class {
44
49
  return slice;
45
50
  }
46
51
  };
52
+ const SIZ_COMPONENT_RECORD_SIZE = 3;
53
+ const SSIZ_SIGNED_BIT = 128;
54
+ const SSIZ_BIT_DEPTH_MASK = 127;
47
55
  function readImageSize(cursor, segmentEnd) {
48
56
  cursor.uint16();
49
57
  const xsiz = cursor.uint32();
@@ -56,13 +64,13 @@ function readImageSize(cursor, segmentEnd) {
56
64
  const ytosiz = cursor.uint32();
57
65
  const count = cursor.uint16();
58
66
  if (count === 0) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("SIZ declares zero components");
59
- if (cursor.position + count * 3 > segmentEnd) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`SIZ declares ${String(count)} components but its own length leaves room for fewer`);
67
+ if (cursor.position + count * SIZ_COMPONENT_RECORD_SIZE > segmentEnd) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`SIZ declares ${String(count)} components but its own length leaves room for fewer`);
60
68
  const components = [];
61
69
  for (let i = 0; i < count; i++) {
62
70
  const ssiz = cursor.uint8();
63
71
  components.push({
64
- signed: (ssiz & 128) !== 0,
65
- bitDepth: (ssiz & 127) + 1,
72
+ signed: (ssiz & SSIZ_SIGNED_BIT) !== 0,
73
+ bitDepth: (ssiz & SSIZ_BIT_DEPTH_MASK) + 1,
66
74
  dx: cursor.uint8(),
67
75
  dy: cursor.uint8()
68
76
  });
@@ -82,20 +90,21 @@ function readImageSize(cursor, segmentEnd) {
82
90
  };
83
91
  }
84
92
  const DEFAULT_PRECINCT_EXPONENT = 15;
93
+ const CODE_BLOCK_AREA_EXPONENT_MAX = 12;
85
94
  function readCodingStyleParameters(cursor, explicitPrecincts) {
86
95
  const decompositionLevels = cursor.uint8();
87
- const codeBlockWidthExp = (cursor.uint8() & 15) + 2;
88
- const codeBlockHeightExp = (cursor.uint8() & 15) + 2;
96
+ const codeBlockWidthExp = (cursor.uint8() & NIBBLE_MASK) + 2;
97
+ const codeBlockHeightExp = (cursor.uint8() & NIBBLE_MASK) + 2;
89
98
  const codeBlockStyle = cursor.uint8();
90
99
  const transformCode = cursor.uint8();
91
100
  if (transformCode !== 0 && transformCode !== 1) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`SPcod/SPcoc declares transformation ${String(transformCode)}, which is neither of the two ISO/IEC 15444-1 defines`);
92
- if (codeBlockWidthExp + codeBlockHeightExp > 12) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`code-block size 2^${String(codeBlockWidthExp)} by 2^${String(codeBlockHeightExp)} is outside the range ISO/IEC 15444-1 Table A.18 permits`);
101
+ if (codeBlockWidthExp + codeBlockHeightExp > CODE_BLOCK_AREA_EXPONENT_MAX) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`code-block size 2^${String(codeBlockWidthExp)} by 2^${String(codeBlockHeightExp)} is outside the range ISO/IEC 15444-1 Table A.18 permits`);
93
102
  const precinctSizes = [];
94
103
  if (explicitPrecincts) for (let r = 0; r <= decompositionLevels; r++) {
95
104
  const packed = cursor.uint8();
96
105
  precinctSizes.push({
97
- ppx: packed & 15,
98
- ppy: packed >> 4 & 15
106
+ ppx: packed & NIBBLE_MASK,
107
+ ppy: packed >> NIBBLE_BITS & NIBBLE_MASK
99
108
  });
100
109
  }
101
110
  else for (let r = 0; r <= decompositionLevels; r++) precinctSizes.push({
@@ -111,6 +120,7 @@ function readCodingStyleParameters(cursor, explicitPrecincts) {
111
120
  precinctSizes
112
121
  };
113
122
  }
123
+ const SCOD_USE_EPH_BIT = 4;
114
124
  function readCodingDefaults(cursor) {
115
125
  const progressionOrders = [
116
126
  "LRCP",
@@ -131,17 +141,22 @@ function readCodingDefaults(cursor) {
131
141
  layers,
132
142
  multipleComponentTransform,
133
143
  useSop: (scod & 2) !== 0,
134
- useEph: (scod & 4) !== 0
144
+ useEph: (scod & SCOD_USE_EPH_BIT) !== 0
135
145
  };
136
146
  }
147
+ const SQCD_GUARD_BITS_SHIFT = 5;
148
+ const SQCD_STYLE_MASK = 31;
149
+ const SPQCD_NONE_EXPONENT_SHIFT = 3;
150
+ const SPQCD_EXPONENT_SHIFT = 11;
151
+ const SPQCD_MANTISSA_MASK = 2047;
137
152
  function readQuantization(cursor, segmentEnd) {
138
153
  const sq = cursor.uint8();
139
- const guardBits = sq >> 5;
140
- const styleCode = sq & 31;
154
+ const guardBits = sq >> SQCD_GUARD_BITS_SHIFT;
155
+ const styleCode = sq & SQCD_STYLE_MASK;
141
156
  const stepSizes = [];
142
157
  if (styleCode === 0) {
143
158
  while (cursor.position < segmentEnd) stepSizes.push({
144
- exponent: cursor.uint8() >> 3,
159
+ exponent: cursor.uint8() >> SPQCD_NONE_EXPONENT_SHIFT,
145
160
  mantissa: 0
146
161
  });
147
162
  return {
@@ -154,8 +169,8 @@ function readQuantization(cursor, segmentEnd) {
154
169
  while (cursor.position + 1 < segmentEnd) {
155
170
  const packed = cursor.uint16();
156
171
  stepSizes.push({
157
- exponent: packed >> 11,
158
- mantissa: packed & 2047
172
+ exponent: packed >> SPQCD_EXPONENT_SHIFT,
173
+ mantissa: packed & SPQCD_MANTISSA_MASK
159
174
  });
160
175
  }
161
176
  return {
@@ -166,8 +181,9 @@ function readQuantization(cursor, segmentEnd) {
166
181
  }
167
182
  throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`QCD/QCC declares quantization style ${String(styleCode)}, which ISO/IEC 15444-1 Table A.28 does not define`);
168
183
  }
184
+ const COMPONENT_INDEX_WIDTH_THRESHOLD = 257;
169
185
  function readComponentIndex(cursor, componentCount) {
170
- return componentCount < 257 ? cursor.uint8() : cursor.uint16();
186
+ return componentCount < COMPONENT_INDEX_WIDTH_THRESHOLD ? cursor.uint8() : cursor.uint16();
171
187
  }
172
188
  function emptyHeader() {
173
189
  return {
@@ -201,11 +217,20 @@ function freezeHeader(header) {
201
217
  };
202
218
  return base;
203
219
  }
220
+ var CodestreamComments = class {
221
+ #texts = [];
222
+ add(text) {
223
+ this.#texts.push(text);
224
+ }
225
+ texts() {
226
+ return this.#texts;
227
+ }
228
+ };
204
229
  function readHeaderSegment(marker, cursor, header, componentCount, comments) {
205
230
  const length = cursor.uint16();
206
- if (length < 2) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`marker segment 0x${marker.toString(16)} declares a length of ${String(length)}, which is shorter than the length field itself`);
231
+ if (length < 2) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`marker segment 0x${marker.toString(HEX_RADIX)} declares a length of ${String(length)}, which is shorter than the length field itself`);
207
232
  const segmentEnd = cursor.position + length - 2;
208
- if (segmentEnd > cursor.data.length) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`marker segment 0x${marker.toString(16)} declares more data than the codestream carries`);
233
+ if (segmentEnd > cursor.data.length) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`marker segment 0x${marker.toString(HEX_RADIX)} declares more data than the codestream carries`);
209
234
  if (marker === MARKER_COD) header.cod = readCodingDefaults(cursor);
210
235
  else if (marker === MARKER_COC) {
211
236
  const component = readComponentIndex(cursor, componentCount);
@@ -220,7 +245,7 @@ function readHeaderSegment(marker, cursor, header, componentCount, comments) {
220
245
  else if (marker === MARKER_COM) {
221
246
  const registration = cursor.uint16();
222
247
  const body = cursor.bytes(segmentEnd - cursor.position);
223
- if (registration === 1) comments.push(Array.from(body, (byte) => String.fromCharCode(byte)).join(""));
248
+ if (registration === 1) comments.add(Array.from(body, (byte) => String.fromCharCode(byte)).join(""));
224
249
  }
225
250
  cursor.position = segmentEnd;
226
251
  }
@@ -228,15 +253,16 @@ function validateMainHeader(header) {
228
253
  if (header.cod === void 0) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("the main header carries no COD marker, so no coding style is defined for any tile");
229
254
  if (header.qcd === void 0) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("the main header carries no QCD marker, so no quantization is defined for any tile");
230
255
  }
256
+ const MIN_HEADER_BYTES = 4;
231
257
  function parseJpeg2000Codestream(data) {
232
258
  const cursor = new MarkerCursor(data);
233
- if (cursor.remaining < 4 || cursor.uint16() !== MARKER_SOC) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("codestream does not begin with an SOC marker");
259
+ if (cursor.remaining < MIN_HEADER_BYTES || cursor.uint16() !== MARKER_SOC) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("codestream does not begin with an SOC marker");
234
260
  if (cursor.uint16() !== MARKER_SIZ) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("the SOC marker is not immediately followed by SIZ, which ISO/IEC 15444-1 A.3 requires");
235
261
  const sizLength = cursor.uint16();
236
262
  const sizEnd = cursor.position + sizLength - 2;
237
263
  const siz = readImageSize(cursor, sizEnd);
238
264
  cursor.position = sizEnd;
239
- const comments = [];
265
+ const comments = new CodestreamComments();
240
266
  const main = emptyHeader();
241
267
  const tileParts = [];
242
268
  let sawEoc = false;
@@ -250,10 +276,10 @@ function parseJpeg2000Codestream(data) {
250
276
  if (marker === MARKER_PPM) throw new require_image_jpeg2000_errors.Jpeg2000UnsupportedError("the codestream carries a PPM marker (packed packet headers in the main header), an organisation this decoder does not reassemble");
251
277
  if (marker === MARKER_SOT) {
252
278
  cursor.position -= 2;
253
- readTilePart(cursor, siz.components.length, tileParts, comments);
279
+ tileParts.push(readTilePart(cursor, siz.components.length, comments));
254
280
  continue;
255
281
  }
256
- if (marker === MARKER_SOD || marker === MARKER_SOC) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`unexpected marker 0x${marker.toString(16)} in the main header`);
282
+ if (marker === MARKER_SOD || marker === MARKER_SOC) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`unexpected marker 0x${marker.toString(HEX_RADIX)} in the main header`);
257
283
  readHeaderSegment(marker, cursor, main, siz.components.length, comments);
258
284
  }
259
285
  validateMainHeader(main);
@@ -264,17 +290,18 @@ function parseJpeg2000Codestream(data) {
264
290
  siz,
265
291
  main: freezeHeader(main),
266
292
  tileParts,
267
- comments,
293
+ comments: comments.texts(),
268
294
  numTilesWide,
269
295
  numTilesHigh,
270
296
  truncated: !sawEoc
271
297
  };
272
298
  }
273
- function readTilePart(cursor, componentCount, tileParts, comments) {
299
+ const SOT_SEGMENT_LENGTH = 10;
300
+ function readTilePart(cursor, componentCount, comments) {
274
301
  const sotStart = cursor.position;
275
302
  cursor.uint16();
276
303
  const lsot = cursor.uint16();
277
- if (lsot !== 10) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`SOT declares a length of ${String(lsot)}, but ISO/IEC 15444-1 A.4.2 fixes it at 10`);
304
+ if (lsot !== SOT_SEGMENT_LENGTH) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`SOT declares a length of ${String(lsot)}, but ISO/IEC 15444-1 A.4.2 fixes it at 10`);
278
305
  const tileIndex = cursor.uint16();
279
306
  const psot = cursor.uint32();
280
307
  const partIndex = cursor.uint8();
@@ -284,7 +311,7 @@ function readTilePart(cursor, componentCount, tileParts, comments) {
284
311
  if (cursor.remaining < 2) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("a tile-part header ended without an SOD marker");
285
312
  const marker = cursor.uint16();
286
313
  if (marker === MARKER_SOD) break;
287
- if (marker === MARKER_SOT || marker === MARKER_EOC) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`a tile-part header ended at marker 0x${marker.toString(16)} rather than at SOD`);
314
+ if (marker === MARKER_SOT || marker === MARKER_EOC) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`a tile-part header ended at marker 0x${marker.toString(HEX_RADIX)} rather than at SOD`);
288
315
  readHeaderSegment(marker, cursor, header, componentCount, comments);
289
316
  }
290
317
  const dataStart = cursor.position;
@@ -292,17 +319,19 @@ function readTilePart(cursor, componentCount, tileParts, comments) {
292
319
  const dataEnd = Math.min(declaredEnd, cursor.data.length);
293
320
  if (dataEnd < dataStart) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("a tile-part declares a Psot shorter than its own header");
294
321
  const trimmedEnd = trimTrailingEoc(cursor.data, dataEnd);
295
- tileParts.push({
322
+ cursor.position = dataEnd;
323
+ return {
296
324
  tileIndex,
297
325
  partIndex,
298
326
  header: freezeHeader(header),
299
327
  dataStart,
300
328
  dataEnd: trimmedEnd
301
- });
302
- cursor.position = dataEnd;
329
+ };
303
330
  }
331
+ const MARKER_EOC_HIGH_BYTE = 255;
332
+ const MARKER_EOC_LOW_BYTE = 217;
304
333
  function trimTrailingEoc(data, end) {
305
- if (data[end - 2] === 255 && data[end - 1] === 217) return end - 2;
334
+ if (data[end - 2] === MARKER_EOC_HIGH_BYTE && data[end - 1] === MARKER_EOC_LOW_BYTE) return end - 2;
306
335
  return end;
307
336
  }
308
337
  //#endregion
@@ -14,6 +14,11 @@ const MARKER_COM = 65380;
14
14
  const MARKER_SOT = 65424;
15
15
  const MARKER_SOD = 65427;
16
16
  const MARKER_EOC = 65497;
17
+ const BITS_PER_BYTE = 8;
18
+ const HEX_RADIX = 16;
19
+ const NIBBLE_MASK = 15;
20
+ const NIBBLE_BITS = 4;
21
+ const UINT16_MODULUS = 65536;
17
22
  var MarkerCursor = class {
18
23
  data;
19
24
  position;
@@ -31,10 +36,10 @@ var MarkerCursor = class {
31
36
  return value;
32
37
  }
33
38
  uint16() {
34
- return this.uint8() << 8 | this.uint8();
39
+ return this.uint8() << BITS_PER_BYTE | this.uint8();
35
40
  }
36
41
  uint32() {
37
- return this.uint16() * 65536 + this.uint16();
42
+ return this.uint16() * UINT16_MODULUS + this.uint16();
38
43
  }
39
44
  bytes(length) {
40
45
  if (length < 0 || this.position + length > this.data.length) throw new Jpeg2000ParseError("a JPEG 2000 marker segment declares more data than the codestream carries");
@@ -43,6 +48,9 @@ var MarkerCursor = class {
43
48
  return slice;
44
49
  }
45
50
  };
51
+ const SIZ_COMPONENT_RECORD_SIZE = 3;
52
+ const SSIZ_SIGNED_BIT = 128;
53
+ const SSIZ_BIT_DEPTH_MASK = 127;
46
54
  function readImageSize(cursor, segmentEnd) {
47
55
  cursor.uint16();
48
56
  const xsiz = cursor.uint32();
@@ -55,13 +63,13 @@ function readImageSize(cursor, segmentEnd) {
55
63
  const ytosiz = cursor.uint32();
56
64
  const count = cursor.uint16();
57
65
  if (count === 0) throw new Jpeg2000ParseError("SIZ declares zero components");
58
- if (cursor.position + count * 3 > segmentEnd) throw new Jpeg2000ParseError(`SIZ declares ${String(count)} components but its own length leaves room for fewer`);
66
+ if (cursor.position + count * SIZ_COMPONENT_RECORD_SIZE > segmentEnd) throw new Jpeg2000ParseError(`SIZ declares ${String(count)} components but its own length leaves room for fewer`);
59
67
  const components = [];
60
68
  for (let i = 0; i < count; i++) {
61
69
  const ssiz = cursor.uint8();
62
70
  components.push({
63
- signed: (ssiz & 128) !== 0,
64
- bitDepth: (ssiz & 127) + 1,
71
+ signed: (ssiz & SSIZ_SIGNED_BIT) !== 0,
72
+ bitDepth: (ssiz & SSIZ_BIT_DEPTH_MASK) + 1,
65
73
  dx: cursor.uint8(),
66
74
  dy: cursor.uint8()
67
75
  });
@@ -81,20 +89,21 @@ function readImageSize(cursor, segmentEnd) {
81
89
  };
82
90
  }
83
91
  const DEFAULT_PRECINCT_EXPONENT = 15;
92
+ const CODE_BLOCK_AREA_EXPONENT_MAX = 12;
84
93
  function readCodingStyleParameters(cursor, explicitPrecincts) {
85
94
  const decompositionLevels = cursor.uint8();
86
- const codeBlockWidthExp = (cursor.uint8() & 15) + 2;
87
- const codeBlockHeightExp = (cursor.uint8() & 15) + 2;
95
+ const codeBlockWidthExp = (cursor.uint8() & NIBBLE_MASK) + 2;
96
+ const codeBlockHeightExp = (cursor.uint8() & NIBBLE_MASK) + 2;
88
97
  const codeBlockStyle = cursor.uint8();
89
98
  const transformCode = cursor.uint8();
90
99
  if (transformCode !== 0 && transformCode !== 1) throw new Jpeg2000ParseError(`SPcod/SPcoc declares transformation ${String(transformCode)}, which is neither of the two ISO/IEC 15444-1 defines`);
91
- if (codeBlockWidthExp + codeBlockHeightExp > 12) throw new Jpeg2000ParseError(`code-block size 2^${String(codeBlockWidthExp)} by 2^${String(codeBlockHeightExp)} is outside the range ISO/IEC 15444-1 Table A.18 permits`);
100
+ if (codeBlockWidthExp + codeBlockHeightExp > CODE_BLOCK_AREA_EXPONENT_MAX) throw new Jpeg2000ParseError(`code-block size 2^${String(codeBlockWidthExp)} by 2^${String(codeBlockHeightExp)} is outside the range ISO/IEC 15444-1 Table A.18 permits`);
92
101
  const precinctSizes = [];
93
102
  if (explicitPrecincts) for (let r = 0; r <= decompositionLevels; r++) {
94
103
  const packed = cursor.uint8();
95
104
  precinctSizes.push({
96
- ppx: packed & 15,
97
- ppy: packed >> 4 & 15
105
+ ppx: packed & NIBBLE_MASK,
106
+ ppy: packed >> NIBBLE_BITS & NIBBLE_MASK
98
107
  });
99
108
  }
100
109
  else for (let r = 0; r <= decompositionLevels; r++) precinctSizes.push({
@@ -110,6 +119,7 @@ function readCodingStyleParameters(cursor, explicitPrecincts) {
110
119
  precinctSizes
111
120
  };
112
121
  }
122
+ const SCOD_USE_EPH_BIT = 4;
113
123
  function readCodingDefaults(cursor) {
114
124
  const progressionOrders = [
115
125
  "LRCP",
@@ -130,17 +140,22 @@ function readCodingDefaults(cursor) {
130
140
  layers,
131
141
  multipleComponentTransform,
132
142
  useSop: (scod & 2) !== 0,
133
- useEph: (scod & 4) !== 0
143
+ useEph: (scod & SCOD_USE_EPH_BIT) !== 0
134
144
  };
135
145
  }
146
+ const SQCD_GUARD_BITS_SHIFT = 5;
147
+ const SQCD_STYLE_MASK = 31;
148
+ const SPQCD_NONE_EXPONENT_SHIFT = 3;
149
+ const SPQCD_EXPONENT_SHIFT = 11;
150
+ const SPQCD_MANTISSA_MASK = 2047;
136
151
  function readQuantization(cursor, segmentEnd) {
137
152
  const sq = cursor.uint8();
138
- const guardBits = sq >> 5;
139
- const styleCode = sq & 31;
153
+ const guardBits = sq >> SQCD_GUARD_BITS_SHIFT;
154
+ const styleCode = sq & SQCD_STYLE_MASK;
140
155
  const stepSizes = [];
141
156
  if (styleCode === 0) {
142
157
  while (cursor.position < segmentEnd) stepSizes.push({
143
- exponent: cursor.uint8() >> 3,
158
+ exponent: cursor.uint8() >> SPQCD_NONE_EXPONENT_SHIFT,
144
159
  mantissa: 0
145
160
  });
146
161
  return {
@@ -153,8 +168,8 @@ function readQuantization(cursor, segmentEnd) {
153
168
  while (cursor.position + 1 < segmentEnd) {
154
169
  const packed = cursor.uint16();
155
170
  stepSizes.push({
156
- exponent: packed >> 11,
157
- mantissa: packed & 2047
171
+ exponent: packed >> SPQCD_EXPONENT_SHIFT,
172
+ mantissa: packed & SPQCD_MANTISSA_MASK
158
173
  });
159
174
  }
160
175
  return {
@@ -165,8 +180,9 @@ function readQuantization(cursor, segmentEnd) {
165
180
  }
166
181
  throw new Jpeg2000ParseError(`QCD/QCC declares quantization style ${String(styleCode)}, which ISO/IEC 15444-1 Table A.28 does not define`);
167
182
  }
183
+ const COMPONENT_INDEX_WIDTH_THRESHOLD = 257;
168
184
  function readComponentIndex(cursor, componentCount) {
169
- return componentCount < 257 ? cursor.uint8() : cursor.uint16();
185
+ return componentCount < COMPONENT_INDEX_WIDTH_THRESHOLD ? cursor.uint8() : cursor.uint16();
170
186
  }
171
187
  function emptyHeader() {
172
188
  return {
@@ -200,11 +216,20 @@ function freezeHeader(header) {
200
216
  };
201
217
  return base;
202
218
  }
219
+ var CodestreamComments = class {
220
+ #texts = [];
221
+ add(text) {
222
+ this.#texts.push(text);
223
+ }
224
+ texts() {
225
+ return this.#texts;
226
+ }
227
+ };
203
228
  function readHeaderSegment(marker, cursor, header, componentCount, comments) {
204
229
  const length = cursor.uint16();
205
- if (length < 2) throw new Jpeg2000ParseError(`marker segment 0x${marker.toString(16)} declares a length of ${String(length)}, which is shorter than the length field itself`);
230
+ if (length < 2) throw new Jpeg2000ParseError(`marker segment 0x${marker.toString(HEX_RADIX)} declares a length of ${String(length)}, which is shorter than the length field itself`);
206
231
  const segmentEnd = cursor.position + length - 2;
207
- if (segmentEnd > cursor.data.length) throw new Jpeg2000ParseError(`marker segment 0x${marker.toString(16)} declares more data than the codestream carries`);
232
+ if (segmentEnd > cursor.data.length) throw new Jpeg2000ParseError(`marker segment 0x${marker.toString(HEX_RADIX)} declares more data than the codestream carries`);
208
233
  if (marker === MARKER_COD) header.cod = readCodingDefaults(cursor);
209
234
  else if (marker === MARKER_COC) {
210
235
  const component = readComponentIndex(cursor, componentCount);
@@ -219,7 +244,7 @@ function readHeaderSegment(marker, cursor, header, componentCount, comments) {
219
244
  else if (marker === MARKER_COM) {
220
245
  const registration = cursor.uint16();
221
246
  const body = cursor.bytes(segmentEnd - cursor.position);
222
- if (registration === 1) comments.push(Array.from(body, (byte) => String.fromCharCode(byte)).join(""));
247
+ if (registration === 1) comments.add(Array.from(body, (byte) => String.fromCharCode(byte)).join(""));
223
248
  }
224
249
  cursor.position = segmentEnd;
225
250
  }
@@ -227,15 +252,16 @@ function validateMainHeader(header) {
227
252
  if (header.cod === void 0) throw new Jpeg2000ParseError("the main header carries no COD marker, so no coding style is defined for any tile");
228
253
  if (header.qcd === void 0) throw new Jpeg2000ParseError("the main header carries no QCD marker, so no quantization is defined for any tile");
229
254
  }
255
+ const MIN_HEADER_BYTES = 4;
230
256
  function parseJpeg2000Codestream(data) {
231
257
  const cursor = new MarkerCursor(data);
232
- if (cursor.remaining < 4 || cursor.uint16() !== MARKER_SOC) throw new Jpeg2000ParseError("codestream does not begin with an SOC marker");
258
+ if (cursor.remaining < MIN_HEADER_BYTES || cursor.uint16() !== MARKER_SOC) throw new Jpeg2000ParseError("codestream does not begin with an SOC marker");
233
259
  if (cursor.uint16() !== MARKER_SIZ) throw new Jpeg2000ParseError("the SOC marker is not immediately followed by SIZ, which ISO/IEC 15444-1 A.3 requires");
234
260
  const sizLength = cursor.uint16();
235
261
  const sizEnd = cursor.position + sizLength - 2;
236
262
  const siz = readImageSize(cursor, sizEnd);
237
263
  cursor.position = sizEnd;
238
- const comments = [];
264
+ const comments = new CodestreamComments();
239
265
  const main = emptyHeader();
240
266
  const tileParts = [];
241
267
  let sawEoc = false;
@@ -249,10 +275,10 @@ function parseJpeg2000Codestream(data) {
249
275
  if (marker === MARKER_PPM) throw new Jpeg2000UnsupportedError("the codestream carries a PPM marker (packed packet headers in the main header), an organisation this decoder does not reassemble");
250
276
  if (marker === MARKER_SOT) {
251
277
  cursor.position -= 2;
252
- readTilePart(cursor, siz.components.length, tileParts, comments);
278
+ tileParts.push(readTilePart(cursor, siz.components.length, comments));
253
279
  continue;
254
280
  }
255
- if (marker === MARKER_SOD || marker === MARKER_SOC) throw new Jpeg2000ParseError(`unexpected marker 0x${marker.toString(16)} in the main header`);
281
+ if (marker === MARKER_SOD || marker === MARKER_SOC) throw new Jpeg2000ParseError(`unexpected marker 0x${marker.toString(HEX_RADIX)} in the main header`);
256
282
  readHeaderSegment(marker, cursor, main, siz.components.length, comments);
257
283
  }
258
284
  validateMainHeader(main);
@@ -263,17 +289,18 @@ function parseJpeg2000Codestream(data) {
263
289
  siz,
264
290
  main: freezeHeader(main),
265
291
  tileParts,
266
- comments,
292
+ comments: comments.texts(),
267
293
  numTilesWide,
268
294
  numTilesHigh,
269
295
  truncated: !sawEoc
270
296
  };
271
297
  }
272
- function readTilePart(cursor, componentCount, tileParts, comments) {
298
+ const SOT_SEGMENT_LENGTH = 10;
299
+ function readTilePart(cursor, componentCount, comments) {
273
300
  const sotStart = cursor.position;
274
301
  cursor.uint16();
275
302
  const lsot = cursor.uint16();
276
- if (lsot !== 10) throw new Jpeg2000ParseError(`SOT declares a length of ${String(lsot)}, but ISO/IEC 15444-1 A.4.2 fixes it at 10`);
303
+ if (lsot !== SOT_SEGMENT_LENGTH) throw new Jpeg2000ParseError(`SOT declares a length of ${String(lsot)}, but ISO/IEC 15444-1 A.4.2 fixes it at 10`);
277
304
  const tileIndex = cursor.uint16();
278
305
  const psot = cursor.uint32();
279
306
  const partIndex = cursor.uint8();
@@ -283,7 +310,7 @@ function readTilePart(cursor, componentCount, tileParts, comments) {
283
310
  if (cursor.remaining < 2) throw new Jpeg2000ParseError("a tile-part header ended without an SOD marker");
284
311
  const marker = cursor.uint16();
285
312
  if (marker === MARKER_SOD) break;
286
- if (marker === MARKER_SOT || marker === MARKER_EOC) throw new Jpeg2000ParseError(`a tile-part header ended at marker 0x${marker.toString(16)} rather than at SOD`);
313
+ if (marker === MARKER_SOT || marker === MARKER_EOC) throw new Jpeg2000ParseError(`a tile-part header ended at marker 0x${marker.toString(HEX_RADIX)} rather than at SOD`);
287
314
  readHeaderSegment(marker, cursor, header, componentCount, comments);
288
315
  }
289
316
  const dataStart = cursor.position;
@@ -291,17 +318,19 @@ function readTilePart(cursor, componentCount, tileParts, comments) {
291
318
  const dataEnd = Math.min(declaredEnd, cursor.data.length);
292
319
  if (dataEnd < dataStart) throw new Jpeg2000ParseError("a tile-part declares a Psot shorter than its own header");
293
320
  const trimmedEnd = trimTrailingEoc(cursor.data, dataEnd);
294
- tileParts.push({
321
+ cursor.position = dataEnd;
322
+ return {
295
323
  tileIndex,
296
324
  partIndex,
297
325
  header: freezeHeader(header),
298
326
  dataStart,
299
327
  dataEnd: trimmedEnd
300
- });
301
- cursor.position = dataEnd;
328
+ };
302
329
  }
330
+ const MARKER_EOC_HIGH_BYTE = 255;
331
+ const MARKER_EOC_LOW_BYTE = 217;
303
332
  function trimTrailingEoc(data, end) {
304
- if (data[end - 2] === 255 && data[end - 1] === 217) return end - 2;
333
+ if (data[end - 2] === MARKER_EOC_HIGH_BYTE && data[end - 1] === MARKER_EOC_LOW_BYTE) return end - 2;
305
334
  return end;
306
335
  }
307
336
  //#endregion
@@ -30,13 +30,14 @@ function interleave(source, bounds, write) {
30
30
  for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.llU0; u < sub.llU1; u++) write(2 * u, 2 * v + 1, source.lh(u, v));
31
31
  for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.hU0; u < sub.hU1; u++) write(2 * u + 1, 2 * v + 1, source.hh(u, v));
32
32
  }
33
+ const LOW_PASS_UPDATE_DIVISOR = 4;
33
34
  function inverse53Filter(buffer, i0, i1) {
34
35
  const base = EXTENSION_MARGIN - i0;
35
36
  const first = Math.floor(i0 / 2) - 1;
36
37
  const last = Math.floor(i1 / 2) + 1;
37
38
  for (let n = first; n <= last; n++) {
38
39
  const index = base + 2 * n;
39
- buffer[index] = (buffer[index] ?? 0) - Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0) + 2) / 4);
40
+ buffer[index] = (buffer[index] ?? 0) - Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0) + 2) / LOW_PASS_UPDATE_DIVISOR);
40
41
  }
41
42
  for (let n = first; n < last; n++) {
42
43
  const index = base + 2 * n + 1;
@@ -29,13 +29,14 @@ function interleave(source, bounds, write) {
29
29
  for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.llU0; u < sub.llU1; u++) write(2 * u, 2 * v + 1, source.lh(u, v));
30
30
  for (let v = sub.hV0; v < sub.hV1; v++) for (let u = sub.hU0; u < sub.hU1; u++) write(2 * u + 1, 2 * v + 1, source.hh(u, v));
31
31
  }
32
+ const LOW_PASS_UPDATE_DIVISOR = 4;
32
33
  function inverse53Filter(buffer, i0, i1) {
33
34
  const base = EXTENSION_MARGIN - i0;
34
35
  const first = Math.floor(i0 / 2) - 1;
35
36
  const last = Math.floor(i1 / 2) + 1;
36
37
  for (let n = first; n <= last; n++) {
37
38
  const index = base + 2 * n;
38
- buffer[index] = (buffer[index] ?? 0) - Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0) + 2) / 4);
39
+ buffer[index] = (buffer[index] ?? 0) - Math.floor(((buffer[index - 1] ?? 0) + (buffer[index + 1] ?? 0) + 2) / LOW_PASS_UPDATE_DIVISOR);
39
40
  }
40
41
  for (let n = first; n < last; n++) {
41
42
  const index = base + 2 * n + 1;
@@ -15,7 +15,9 @@ const STYLE_TERMINATE_ALL = 4;
15
15
  const STYLE_VERTICALLY_CAUSAL = 8;
16
16
  const STYLE_SEGMENTATION_SYMBOLS = 32;
17
17
  const SEGMENTATION_SYMBOL = 10;
18
+ const SEGMENTATION_SYMBOL_MSB_SHIFT = 3;
18
19
  const STRIPE_HEIGHT = 4;
20
+ const HEX_RADIX = 16;
19
21
  const PASS_SIGNIFICANCE = 0;
20
22
  const PASS_REFINEMENT = 1;
21
23
  const PASS_CLEANUP = 2;
@@ -23,25 +25,33 @@ function throwForUnsupportedStyle(style) {
23
25
  if ((style & STYLE_SELECTIVE_BYPASS) !== 0) throw new require_image_jpeg2000_errors.Jpeg2000UnsupportedError("the code-block style enables selective arithmetic coding bypass (lazy mode), which splits a code-block into raw and arithmetically coded segments this decoder does not read");
24
26
  if ((style & STYLE_TERMINATE_ALL) !== 0) throw new require_image_jpeg2000_errors.Jpeg2000UnsupportedError("the code-block style terminates the arithmetic coder on every coding pass, which splits a code-block into one segment per pass this decoder does not read");
25
27
  }
28
+ const ZC_CONTEXT_3 = 3;
29
+ const ZC_CONTEXT_4 = 4;
30
+ const ZC_CONTEXT_5 = 5;
31
+ const ZC_CONTEXT_6 = 6;
32
+ const ZC_CONTEXT_7 = 7;
33
+ const ZC_CONTEXT_8 = 8;
34
+ const HH_DIAGONAL_NEIGHBOURS_HIGH = 3;
26
35
  function zeroCodingContext(subband, horizontal, vertical, diagonal) {
27
36
  if (subband === "HH") {
28
37
  const straight = horizontal + vertical;
29
- if (diagonal >= 3) return 8;
30
- if (diagonal === 2) return straight >= 1 ? 7 : 6;
31
- if (diagonal === 1) return straight >= 2 ? 5 : straight === 1 ? 4 : 3;
38
+ if (diagonal >= HH_DIAGONAL_NEIGHBOURS_HIGH) return ZC_CONTEXT_8;
39
+ if (diagonal === 2) return straight >= 1 ? ZC_CONTEXT_7 : ZC_CONTEXT_6;
40
+ if (diagonal === 1) return straight >= 2 ? ZC_CONTEXT_5 : straight === 1 ? ZC_CONTEXT_4 : ZC_CONTEXT_3;
32
41
  return straight >= 2 ? 2 : straight === 1 ? 1 : 0;
33
42
  }
34
43
  const primary = subband === "HL" ? vertical : horizontal;
35
44
  const secondary = subband === "HL" ? horizontal : vertical;
36
- if (primary === 2) return 8;
45
+ if (primary === 2) return ZC_CONTEXT_8;
37
46
  if (primary === 1) {
38
- if (secondary >= 1) return 7;
39
- return diagonal >= 1 ? 6 : 5;
47
+ if (secondary >= 1) return ZC_CONTEXT_7;
48
+ return diagonal >= 1 ? ZC_CONTEXT_6 : ZC_CONTEXT_5;
40
49
  }
41
- if (secondary === 2) return 4;
42
- if (secondary === 1) return 3;
50
+ if (secondary === 2) return ZC_CONTEXT_4;
51
+ if (secondary === 1) return ZC_CONTEXT_3;
43
52
  return diagonal >= 2 ? 2 : diagonal === 1 ? 1 : 0;
44
53
  }
54
+ const SIGN_CONTEXT_TABLE_ROW_STRIDE = 3;
45
55
  const SIGN_XOR_FLAG = 8;
46
56
  const SIGN_CONTEXT_TABLE = [
47
57
  12,
@@ -102,7 +112,7 @@ function decodeJpeg2000CodeBlock(options) {
102
112
  const below = belowVisible(y, stripeEnd);
103
113
  const horizontal = clampToUnit(contribution(n - 1) + contribution(n + 1));
104
114
  const vertical = clampToUnit(contribution(n - stride) + (below ? contribution(n + stride) : 0));
105
- const packed = SIGN_CONTEXT_TABLE[(horizontal + 1) * 3 + (vertical + 1)] ?? 0;
115
+ const packed = SIGN_CONTEXT_TABLE[(horizontal + 1) * SIGN_CONTEXT_TABLE_ROW_STRIDE + (vertical + 1)] ?? 0;
106
116
  const decision = mq.decode(contexts, SIGN_CONTEXT_BASE + (packed & -9));
107
117
  negative[n] = decision ^ ((packed & SIGN_XOR_FLAG) !== 0 ? 1 : 0);
108
118
  };
@@ -160,8 +170,8 @@ function decodeJpeg2000CodeBlock(options) {
160
170
  }
161
171
  }
162
172
  if (segmentationSymbols) {
163
- const symbol = mq.decode(contexts, UNIFORM_CONTEXT) << 3 | mq.decode(contexts, UNIFORM_CONTEXT) << 2 | mq.decode(contexts, UNIFORM_CONTEXT) << 1 | mq.decode(contexts, UNIFORM_CONTEXT);
164
- if (symbol !== SEGMENTATION_SYMBOL) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`a cleanup pass ended with segmentation symbol 0x${symbol.toString(16)} rather than the 0xA ISO/IEC 15444-1 D.3.4 requires, so this code-block's coded data is corrupt`);
173
+ const symbol = mq.decode(contexts, UNIFORM_CONTEXT) << SEGMENTATION_SYMBOL_MSB_SHIFT | mq.decode(contexts, UNIFORM_CONTEXT) << 2 | mq.decode(contexts, UNIFORM_CONTEXT) << 1 | mq.decode(contexts, UNIFORM_CONTEXT);
174
+ if (symbol !== SEGMENTATION_SYMBOL) throw new require_image_jpeg2000_errors.Jpeg2000ParseError(`a cleanup pass ended with segmentation symbol 0x${symbol.toString(HEX_RADIX)} rather than the 0xA ISO/IEC 15444-1 D.3.4 requires, so this code-block's coded data is corrupt`);
165
175
  }
166
176
  codedThisPlane.fill(0);
167
177
  };