pdf-parser.js 5.2.27 → 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.
- package/dist/{afm-widths-BYiX2L9D.cjs → afm-widths-BHD2HZIL.cjs} +553 -642
- package/dist/{afm-widths-blUDDjlI.js → afm-widths-B_IGbGky.js} +553 -642
- package/dist/afm-widths.cjs +1 -1
- package/dist/afm-widths.js +1 -1
- package/dist/annotations.cjs +5 -3
- package/dist/annotations.js +5 -3
- package/dist/builtin-encoding.cjs +17 -6
- package/dist/builtin-encoding.js +17 -6
- package/dist/bytes/crc32.cjs +5 -3
- package/dist/bytes/crc32.js +5 -3
- package/dist/bytes/flate.cjs +0 -1
- package/dist/bytes/flate.js +0 -1
- package/dist/cff-bounds.cjs +42 -24
- package/dist/cff-bounds.js +42 -24
- package/dist/cff.cjs +13 -6
- package/dist/cff.js +13 -6
- package/dist/cmap-table.cjs +54 -26
- package/dist/cmap-table.js +54 -26
- package/dist/cmap.cjs +5 -3
- package/dist/cmap.js +5 -3
- package/dist/content-write.cjs +3 -2
- package/dist/content-write.js +3 -2
- package/dist/crypto/aes.cjs +76 -55
- package/dist/crypto/aes.js +76 -55
- package/dist/crypto/md5.cjs +345 -149
- package/dist/crypto/md5.js +345 -149
- package/dist/crypto/rc4.cjs +5 -4
- package/dist/crypto/rc4.js +5 -4
- package/dist/crypto/sha2.cjs +92 -43
- package/dist/crypto/sha2.js +92 -43
- package/dist/embedded-font.cjs +4 -2
- package/dist/embedded-font.js +4 -2
- package/dist/encoding.cjs +1 -1
- package/dist/encoding.js +1 -1
- package/dist/encrypt-write.cjs +25 -21
- package/dist/encrypt-write.js +25 -21
- package/dist/encrypt.cjs +43 -64
- package/dist/encrypt.js +43 -64
- package/dist/filters.cjs +40 -20
- package/dist/filters.js +40 -20
- package/dist/font-face.cjs +2 -1
- package/dist/font-face.js +2 -1
- package/dist/font-read.cjs +12 -6
- package/dist/font-read.js +12 -6
- package/dist/font-tables.cjs +55 -28
- package/dist/font-tables.js +55 -28
- package/dist/gdef-table.cjs +6 -3
- package/dist/gdef-table.js +6 -3
- package/dist/glyf-contours.cjs +3 -1
- package/dist/glyf-contours.js +3 -1
- package/dist/glyf.cjs +22 -11
- package/dist/glyf.js +22 -11
- package/dist/gpos-table.cjs +37 -19
- package/dist/gpos-table.js +37 -19
- package/dist/gsub-table.cjs +28 -17
- package/dist/gsub-table.js +28 -17
- package/dist/hmtx-table.cjs +5 -3
- package/dist/hmtx-table.js +5 -3
- package/dist/image/ccitt-encode.cjs +8 -5
- package/dist/image/ccitt-encode.js +8 -5
- package/dist/image/ccitt.cjs +801 -209
- package/dist/image/ccitt.js +801 -209
- package/dist/image/jbig2-arith.cjs +340 -306
- package/dist/image/jbig2-arith.js +340 -306
- package/dist/image/jbig2-bitmap.cjs +8 -5
- package/dist/image/jbig2-bitmap.js +8 -5
- package/dist/image/jbig2-generic.cjs +240 -69
- package/dist/image/jbig2-generic.js +240 -69
- package/dist/image/jbig2-text.cjs +4 -2
- package/dist/image/jbig2-text.js +4 -2
- package/dist/image/jbig2.cjs +69 -31
- package/dist/image/jbig2.js +69 -31
- package/dist/image/jp2-boxes.cjs +52 -27
- package/dist/image/jp2-boxes.js +52 -27
- package/dist/image/jpeg-info.cjs +29 -24
- package/dist/image/jpeg-info.js +29 -24
- package/dist/image/jpeg2000-codestream.cjs +44 -24
- package/dist/image/jpeg2000-codestream.js +44 -24
- package/dist/image/jpeg2000-dwt.cjs +2 -1
- package/dist/image/jpeg2000-dwt.js +2 -1
- package/dist/image/jpeg2000-t1.cjs +21 -11
- package/dist/image/jpeg2000-t1.js +21 -11
- package/dist/image/jpeg2000-t2.cjs +12 -5
- package/dist/image/jpeg2000-t2.js +12 -5
- package/dist/image/jpeg2000-tagtree.cjs +8 -4
- package/dist/image/jpeg2000-tagtree.js +8 -4
- package/dist/image/jpeg2000.cjs +11 -6
- package/dist/image/jpeg2000.js +11 -6
- package/dist/image/png-decode.cjs +62 -39
- package/dist/image/png-decode.d.cts +3 -2
- package/dist/image/png-decode.d.ts +3 -2
- package/dist/image/png-decode.js +62 -39
- package/dist/image/png-filter.cjs +23 -15
- package/dist/image/png-filter.js +23 -15
- package/dist/images-read.cjs +41 -36
- package/dist/images-read.js +41 -36
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/interpret.cjs +39 -24
- package/dist/interpret.js +39 -24
- package/dist/lexer.cjs +86 -51
- package/dist/lexer.js +86 -51
- package/dist/math-content-write.cjs +9 -5
- package/dist/math-content-write.js +9 -5
- package/dist/math-font-write.cjs +2 -1
- package/dist/math-font-write.js +2 -1
- package/dist/math-font.cjs +16 -7
- package/dist/math-font.js +16 -7
- package/dist/math-table.cjs +25 -13
- package/dist/math-table.js +25 -13
- package/dist/matrix.cjs +3 -2
- package/dist/matrix.js +3 -2
- package/dist/measure.cjs +1 -1
- package/dist/measure.js +1 -1
- package/dist/navigation.cjs +10 -5
- package/dist/navigation.js +10 -5
- package/dist/ot-layout-common.cjs +4 -2
- package/dist/ot-layout-common.js +4 -2
- package/dist/parse.cjs +7 -5
- package/dist/parse.js +7 -5
- package/dist/pdf-text.cjs +5 -2
- package/dist/pdf-text.js +5 -2
- package/dist/predictors.cjs +14 -9
- package/dist/predictors.js +14 -9
- package/dist/raster.cjs +30 -19
- package/dist/raster.js +30 -19
- package/dist/read.cjs +17 -8
- package/dist/read.js +17 -8
- package/dist/serialize.cjs +6 -2
- package/dist/serialize.js +6 -2
- package/dist/sfnt-subset.cjs +25 -13
- package/dist/sfnt-subset.js +25 -13
- package/dist/sfnt.cjs +20 -10
- package/dist/sfnt.js +20 -10
- package/dist/text-group.cjs +0 -1
- package/dist/text-group.js +0 -1
- package/dist/tounicode.cjs +4 -2
- package/dist/tounicode.js +4 -2
- package/dist/winansi.cjs +1 -1
- package/dist/winansi.js +1 -1
- package/dist/write.cjs +20 -12
- package/dist/write.js +20 -12
- package/dist/xref.cjs +5 -2
- package/dist/xref.js +5 -2
- package/package.json +1 -1
package/dist/image/jbig2.js
CHANGED
|
@@ -28,6 +28,44 @@ const SEGMENT_TABLES = 53;
|
|
|
28
28
|
const SEGMENT_EXTENSION = 62;
|
|
29
29
|
const UNKNOWN_DATA_LENGTH = 4294967295;
|
|
30
30
|
const UNKNOWN_PAGE_HEIGHT = 4294967295;
|
|
31
|
+
const BITS_PER_BYTE = 8;
|
|
32
|
+
const UINT8_MODULUS = 256;
|
|
33
|
+
const INT8_MAX = UINT8_MODULUS / 2 - 1;
|
|
34
|
+
const UINT32_BYTE_2_SHIFT = 16;
|
|
35
|
+
const UINT32_BYTE_3_SHIFT = 24;
|
|
36
|
+
const SEGMENT_TYPE_MASK = 63;
|
|
37
|
+
const PAGE_ASSOCIATION_SIZE_FLAG = 64;
|
|
38
|
+
const REFERRED_COUNT_SHORT_SHIFT = 5;
|
|
39
|
+
const REFERRED_COUNT_LONG_FORM_SENTINEL = 7;
|
|
40
|
+
const REFERRED_COUNT_LONG_MASK = 536870911;
|
|
41
|
+
const SEGMENT_NUMBER_1BYTE_LIMIT = 256;
|
|
42
|
+
const SEGMENT_NUMBER_2BYTE_LIMIT = 65536;
|
|
43
|
+
const REFERRED_NUMBER_SIZE_4_BYTES = 4;
|
|
44
|
+
const REGION_COMBOP_MASK = 7;
|
|
45
|
+
const PAGE_DEFAULT_COMBOP_SHIFT = 3;
|
|
46
|
+
const PAGE_DEFAULT_COMBOP_MASK = 3;
|
|
47
|
+
const PAGE_COMBOP_OVERRIDE_FLAG = 64;
|
|
48
|
+
const GENERIC_CODING_AT_PIXEL_COUNT_TEMPLATE_0 = 4;
|
|
49
|
+
const GENERIC_TEMPLATE_0_CONTEXT_BITS = 16;
|
|
50
|
+
const REFINEMENT_TEMPLATE_0_CONTEXT_BITS = 13;
|
|
51
|
+
const GENERIC_REGION_TEMPLATE_MASK = 3;
|
|
52
|
+
const GENERIC_REGION_TPGDON_FLAG = 8;
|
|
53
|
+
const GENERIC_REGION_EXTTEMPLATE_FLAG = 16;
|
|
54
|
+
const SYMBOL_DICT_BITMAP_CODING_CONTEXT_USED = 256;
|
|
55
|
+
const SYMBOL_DICT_BITMAP_CODING_CONTEXT_RETAINED = 512;
|
|
56
|
+
const SYMBOL_DICT_TEMPLATE_SHIFT = 10;
|
|
57
|
+
const SYMBOL_DICT_TEMPLATE_MASK = 3;
|
|
58
|
+
const SYMBOL_DICT_REFINEMENT_TEMPLATE_SHIFT = 12;
|
|
59
|
+
const TEXT_REGION_STRIP_SIZE_LOG_MASK = 3;
|
|
60
|
+
const TEXT_REGION_REFCORNER_SHIFT = 4;
|
|
61
|
+
const TEXT_REGION_REFCORNER_MASK = 3;
|
|
62
|
+
const TEXT_REGION_TRANSPOSED_FLAG = 64;
|
|
63
|
+
const TEXT_REGION_SBCOMBOP_SHIFT = 7;
|
|
64
|
+
const TEXT_REGION_SBCOMBOP_MASK = 3;
|
|
65
|
+
const TEXT_REGION_DEFAULT_PIXEL_SHIFT = 9;
|
|
66
|
+
const TEXT_REGION_REFINEMENT_TEMPLATE_SHIFT = 15;
|
|
67
|
+
const SBDSOFFSET_SIGN_EXTEND_LEFT_SHIFT = 17;
|
|
68
|
+
const SBDSOFFSET_SIGN_EXTEND_RIGHT_SHIFT = 27;
|
|
31
69
|
var ByteCursor = class {
|
|
32
70
|
data;
|
|
33
71
|
position;
|
|
@@ -45,28 +83,28 @@ var ByteCursor = class {
|
|
|
45
83
|
return value;
|
|
46
84
|
}
|
|
47
85
|
uint16() {
|
|
48
|
-
return this.uint8() <<
|
|
86
|
+
return this.uint8() << BITS_PER_BYTE | this.uint8();
|
|
49
87
|
}
|
|
50
88
|
uint32() {
|
|
51
|
-
return (this.uint8() <<
|
|
89
|
+
return (this.uint8() << UINT32_BYTE_3_SHIFT | this.uint8() << UINT32_BYTE_2_SHIFT | this.uint8() << BITS_PER_BYTE | this.uint8()) >>> 0;
|
|
52
90
|
}
|
|
53
91
|
int8() {
|
|
54
92
|
const value = this.uint8();
|
|
55
|
-
return value >
|
|
93
|
+
return value > INT8_MAX ? value - UINT8_MODULUS : value;
|
|
56
94
|
}
|
|
57
95
|
};
|
|
58
96
|
function readSegmentHeader(cursor, dataLength) {
|
|
59
97
|
const number = cursor.uint32();
|
|
60
98
|
const flags = cursor.uint8();
|
|
61
|
-
const type = flags &
|
|
62
|
-
const pageAssociationIsLong = (flags &
|
|
63
|
-
let referredCount = cursor.uint8() >>
|
|
64
|
-
if (referredCount ===
|
|
99
|
+
const type = flags & SEGMENT_TYPE_MASK;
|
|
100
|
+
const pageAssociationIsLong = (flags & PAGE_ASSOCIATION_SIZE_FLAG) !== 0;
|
|
101
|
+
let referredCount = cursor.uint8() >> REFERRED_COUNT_SHORT_SHIFT;
|
|
102
|
+
if (referredCount === REFERRED_COUNT_LONG_FORM_SENTINEL) {
|
|
65
103
|
cursor.position -= 1;
|
|
66
|
-
referredCount = cursor.uint32() &
|
|
67
|
-
cursor.position += Math.ceil((referredCount + 1) /
|
|
104
|
+
referredCount = cursor.uint32() & REFERRED_COUNT_LONG_MASK;
|
|
105
|
+
cursor.position += Math.ceil((referredCount + 1) / BITS_PER_BYTE);
|
|
68
106
|
}
|
|
69
|
-
const referredSize = number <=
|
|
107
|
+
const referredSize = number <= SEGMENT_NUMBER_1BYTE_LIMIT ? 1 : number <= SEGMENT_NUMBER_2BYTE_LIMIT ? 2 : REFERRED_NUMBER_SIZE_4_BYTES;
|
|
70
108
|
const referredTo = [];
|
|
71
109
|
for (let i = 0; i < referredCount; i++) referredTo.push(referredSize === 1 ? cursor.uint8() : referredSize === 2 ? cursor.uint16() : cursor.uint32());
|
|
72
110
|
const pageAssociation = pageAssociationIsLong ? cursor.uint32() : cursor.uint8();
|
|
@@ -90,8 +128,8 @@ function readRegionInfo(cursor) {
|
|
|
90
128
|
const x = cursor.uint32();
|
|
91
129
|
const y = cursor.uint32();
|
|
92
130
|
const flags = cursor.uint8();
|
|
93
|
-
const combinationOperator = combinationOperatorFromCode(flags &
|
|
94
|
-
if (combinationOperator === void 0) throw new Jbig2ParseError(`JBIG2 region declares external combination operator ${String(flags &
|
|
131
|
+
const combinationOperator = combinationOperatorFromCode(flags & REGION_COMBOP_MASK);
|
|
132
|
+
if (combinationOperator === void 0) throw new Jbig2ParseError(`JBIG2 region declares external combination operator ${String(flags & REGION_COMBOP_MASK)}, outside the 0-4 range T.88 Table 12 defines`);
|
|
95
133
|
return {
|
|
96
134
|
width,
|
|
97
135
|
height,
|
|
@@ -174,12 +212,12 @@ var Jbig2Decoder = class {
|
|
|
174
212
|
const declaredOrHintedHeight = declaredHeight === UNKNOWN_PAGE_HEIGHT ? this.options.height : this.options.height ?? declaredHeight;
|
|
175
213
|
if (declaredOrHintedHeight === void 0) throw new Jbig2UnsupportedError("JBIG2 page information declares an unknown height and the caller supplied none; a striped page with no known height is not resolvable from the page segments alone");
|
|
176
214
|
const defaultPixel = flags >> 2 & 1;
|
|
177
|
-
const defaultCombinationOperator = combinationOperatorFromCode(flags >>
|
|
215
|
+
const defaultCombinationOperator = combinationOperatorFromCode(flags >> PAGE_DEFAULT_COMBOP_SHIFT & PAGE_DEFAULT_COMBOP_MASK);
|
|
178
216
|
if (defaultCombinationOperator === void 0) throw new Jbig2ParseError("JBIG2 page information declares an unrecognised default combination operator");
|
|
179
217
|
this.page = {
|
|
180
218
|
bitmap: createBitmap(width, declaredOrHintedHeight, defaultPixel),
|
|
181
219
|
defaultCombinationOperator,
|
|
182
|
-
combinationOperatorOverridden: (flags &
|
|
220
|
+
combinationOperatorOverridden: (flags & PAGE_COMBOP_OVERRIDE_FLAG) !== 0
|
|
183
221
|
};
|
|
184
222
|
}
|
|
185
223
|
requirePage() {
|
|
@@ -194,10 +232,10 @@ var Jbig2Decoder = class {
|
|
|
194
232
|
const region = readRegionInfo(cursor);
|
|
195
233
|
const flags = cursor.uint8();
|
|
196
234
|
const mmr = (flags & 1) !== 0;
|
|
197
|
-
const template = flags >> 1 &
|
|
198
|
-
const tpgdon = (flags &
|
|
199
|
-
if ((flags &
|
|
200
|
-
const at = mmr ? [] : readAtPixels(cursor, template === 0 ?
|
|
235
|
+
const template = flags >> 1 & GENERIC_REGION_TEMPLATE_MASK;
|
|
236
|
+
const tpgdon = (flags & GENERIC_REGION_TPGDON_FLAG) !== 0;
|
|
237
|
+
if ((flags & GENERIC_REGION_EXTTEMPLATE_FLAG) !== 0) throw new Jbig2UnsupportedError("JBIG2 generic region sets EXTTEMPLATE, the twelve-adaptive-pixel template of T.88 Amendment 2, which is not implemented");
|
|
238
|
+
const at = mmr ? [] : readAtPixels(cursor, template === 0 ? GENERIC_CODING_AT_PIXEL_COUNT_TEMPLATE_0 : 1);
|
|
201
239
|
const payload = cursor.position;
|
|
202
240
|
if (mmr) {
|
|
203
241
|
const fax = decodeCcittFax(cursor.data.subarray(payload, dataEnd), {
|
|
@@ -213,7 +251,7 @@ var Jbig2Decoder = class {
|
|
|
213
251
|
return;
|
|
214
252
|
}
|
|
215
253
|
const mq = new MqDecoder(cursor.data, payload, dataEnd);
|
|
216
|
-
const contexts = createArithContexts(GENERIC_CONTEXT_BITS[template] ??
|
|
254
|
+
const contexts = createArithContexts(GENERIC_CONTEXT_BITS[template] ?? GENERIC_TEMPLATE_0_CONTEXT_BITS);
|
|
217
255
|
this.compose(region, decodeGenericRegion(region.width, region.height, {
|
|
218
256
|
template,
|
|
219
257
|
tpgdon,
|
|
@@ -230,7 +268,7 @@ var Jbig2Decoder = class {
|
|
|
230
268
|
const reference = createBitmap(region.width, region.height);
|
|
231
269
|
for (let y = 0; y < region.height; y++) for (let x = 0; x < region.width; x++) reference.data[y * region.width + x] = getPixel(page.bitmap, region.x + x, region.y + y);
|
|
232
270
|
const mq = new MqDecoder(cursor.data, cursor.position, dataEnd);
|
|
233
|
-
const contexts = createArithContexts(REFINEMENT_CONTEXT_BITS[template] ??
|
|
271
|
+
const contexts = createArithContexts(REFINEMENT_CONTEXT_BITS[template] ?? REFINEMENT_TEMPLATE_0_CONTEXT_BITS);
|
|
234
272
|
const refined = decodeRefinementRegion(region.width, region.height, {
|
|
235
273
|
template,
|
|
236
274
|
tpgron,
|
|
@@ -244,11 +282,11 @@ var Jbig2Decoder = class {
|
|
|
244
282
|
readSymbolDictionary(header, cursor) {
|
|
245
283
|
const flags = cursor.uint16();
|
|
246
284
|
if ((flags & 1) !== 0) throw new Jbig2UnsupportedError("JBIG2 symbol dictionary is Huffman-coded (SDHUFF = 1); only the arithmetic form is implemented");
|
|
247
|
-
if ((flags &
|
|
285
|
+
if ((flags & SYMBOL_DICT_BITMAP_CODING_CONTEXT_USED) !== 0 || (flags & SYMBOL_DICT_BITMAP_CODING_CONTEXT_RETAINED) !== 0) throw new Jbig2UnsupportedError("JBIG2 symbol dictionary uses or retains a shared bitmap coding context (T.88 7.4.3.1.1 bits 8-9), which is not implemented");
|
|
248
286
|
const refinementAggregate = (flags & 2) !== 0;
|
|
249
|
-
const template = flags >>
|
|
250
|
-
const refinementTemplate = flags >>
|
|
251
|
-
const at = readAtPixels(cursor, template === 0 ?
|
|
287
|
+
const template = flags >> SYMBOL_DICT_TEMPLATE_SHIFT & SYMBOL_DICT_TEMPLATE_MASK;
|
|
288
|
+
const refinementTemplate = flags >> SYMBOL_DICT_REFINEMENT_TEMPLATE_SHIFT & 1;
|
|
289
|
+
const at = readAtPixels(cursor, template === 0 ? GENERIC_CODING_AT_PIXEL_COUNT_TEMPLATE_0 : 1);
|
|
252
290
|
const refinementAt = refinementAggregate && refinementTemplate === 0 ? readAtPixels(cursor, 2) : [...NOMINAL_REFINEMENT_AT];
|
|
253
291
|
const exportedSymbolCount = cursor.uint32();
|
|
254
292
|
const newSymbolCount = cursor.uint32();
|
|
@@ -272,15 +310,15 @@ var Jbig2Decoder = class {
|
|
|
272
310
|
const flags = cursor.uint16();
|
|
273
311
|
if ((flags & 1) !== 0) throw new Jbig2UnsupportedError("JBIG2 text region is Huffman-coded (SBHUFF = 1); only the arithmetic form is implemented");
|
|
274
312
|
const refine = (flags & 2) !== 0;
|
|
275
|
-
const stripSize = 1 << (flags >> 2 &
|
|
276
|
-
const referenceCorner = referenceCornerFromCode(flags >>
|
|
313
|
+
const stripSize = 1 << (flags >> 2 & TEXT_REGION_STRIP_SIZE_LOG_MASK);
|
|
314
|
+
const referenceCorner = referenceCornerFromCode(flags >> TEXT_REGION_REFCORNER_SHIFT & TEXT_REGION_REFCORNER_MASK);
|
|
277
315
|
if (referenceCorner === void 0) throw new Jbig2ParseError("JBIG2 text region declares an unrecognised REFCORNER");
|
|
278
|
-
const transposed = (flags &
|
|
279
|
-
const combinationOperator = combinationOperatorFromCode(flags >>
|
|
316
|
+
const transposed = (flags & TEXT_REGION_TRANSPOSED_FLAG) !== 0;
|
|
317
|
+
const combinationOperator = combinationOperatorFromCode(flags >> TEXT_REGION_SBCOMBOP_SHIFT & TEXT_REGION_SBCOMBOP_MASK);
|
|
280
318
|
if (combinationOperator === void 0) throw new Jbig2ParseError("JBIG2 text region declares an unrecognised SBCOMBOP");
|
|
281
|
-
const defaultPixel = flags >>
|
|
282
|
-
const dsOffset = flags <<
|
|
283
|
-
const refinementTemplate = flags >>
|
|
319
|
+
const defaultPixel = flags >> TEXT_REGION_DEFAULT_PIXEL_SHIFT & 1;
|
|
320
|
+
const dsOffset = flags << SBDSOFFSET_SIGN_EXTEND_LEFT_SHIFT >> SBDSOFFSET_SIGN_EXTEND_RIGHT_SHIFT | 0;
|
|
321
|
+
const refinementTemplate = flags >> TEXT_REGION_REFINEMENT_TEMPLATE_SHIFT & 1;
|
|
284
322
|
const refinementAt = refine && refinementTemplate === 0 ? readAtPixels(cursor, 2) : [...NOMINAL_REFINEMENT_AT];
|
|
285
323
|
const instanceCount = cursor.uint32();
|
|
286
324
|
const symbols = this.gatherSymbols(header.referredTo);
|
package/dist/image/jp2-boxes.cjs
CHANGED
|
@@ -4,6 +4,11 @@ const require_image_jpeg2000_errors = require("./jpeg2000-errors.cjs");
|
|
|
4
4
|
const BOX_HEADER_BYTES = 8;
|
|
5
5
|
const BOX_LENGTH_EXTENDED = 1;
|
|
6
6
|
const BOX_LENGTH_TO_END = 0;
|
|
7
|
+
const BITS_PER_BYTE = 8;
|
|
8
|
+
const BYTE_0_MULTIPLIER = 16777216;
|
|
9
|
+
const BYTE_1_SHIFT = 16;
|
|
10
|
+
const UINT32_SIZE = 4;
|
|
11
|
+
const UINT32_LAST_BYTE_OFFSET = 3;
|
|
7
12
|
const BOX_SIGNATURE = 1783636e3;
|
|
8
13
|
const BOX_JP2_HEADER = 1785737832;
|
|
9
14
|
const BOX_IMAGE_HEADER = 1768449138;
|
|
@@ -12,26 +17,29 @@ const BOX_PALETTE = 1885564018;
|
|
|
12
17
|
const BOX_COMPONENT_MAPPING = 1668112752;
|
|
13
18
|
const BOX_CHANNEL_DEFINITION = 1667523942;
|
|
14
19
|
const BOX_CONTIGUOUS_CODESTREAM = 1785737827;
|
|
20
|
+
const JPEG2000_MARKER_PREFIX = 255;
|
|
21
|
+
const JPEG2000_SOC_LOW_BYTE = 79;
|
|
22
|
+
const JPEG2000_SIZ_LOW_BYTE = 81;
|
|
15
23
|
function looksLikeBareCodestream(data) {
|
|
16
|
-
return data[0] ===
|
|
24
|
+
return data[0] === JPEG2000_MARKER_PREFIX && data[1] === JPEG2000_SOC_LOW_BYTE && data[2] === JPEG2000_MARKER_PREFIX && data[3] === JPEG2000_SIZ_LOW_BYTE;
|
|
17
25
|
}
|
|
18
26
|
function readUint32(data, offset) {
|
|
19
27
|
const b0 = data[offset];
|
|
20
28
|
const b1 = data[offset + 1];
|
|
21
29
|
const b2 = data[offset + 2];
|
|
22
|
-
const b3 = data[offset +
|
|
30
|
+
const b3 = data[offset + UINT32_LAST_BYTE_OFFSET];
|
|
23
31
|
if (b0 === void 0 || b1 === void 0 || b2 === void 0 || b3 === void 0) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("JP2 box structure ended in the middle of a 32-bit field");
|
|
24
|
-
return b0 *
|
|
32
|
+
return b0 * BYTE_0_MULTIPLIER + (b1 << BYTE_1_SHIFT) + (b2 << BITS_PER_BYTE) + b3;
|
|
25
33
|
}
|
|
26
34
|
function readBox(data, offset, limit) {
|
|
27
35
|
if (offset + BOX_HEADER_BYTES > limit) return;
|
|
28
36
|
const declaredLength = readUint32(data, offset);
|
|
29
|
-
const type = readUint32(data, offset +
|
|
37
|
+
const type = readUint32(data, offset + UINT32_SIZE);
|
|
30
38
|
let payloadStart = offset + BOX_HEADER_BYTES;
|
|
31
39
|
let boxEnd;
|
|
32
40
|
if (declaredLength === BOX_LENGTH_EXTENDED) {
|
|
33
41
|
const high = readUint32(data, payloadStart);
|
|
34
|
-
const low = readUint32(data, payloadStart +
|
|
42
|
+
const low = readUint32(data, payloadStart + UINT32_SIZE);
|
|
35
43
|
payloadStart += 8;
|
|
36
44
|
boxEnd = high === 0 ? offset + low : limit;
|
|
37
45
|
} else if (declaredLength === BOX_LENGTH_TO_END) boxEnd = limit;
|
|
@@ -45,12 +53,18 @@ function readBox(data, offset, limit) {
|
|
|
45
53
|
};
|
|
46
54
|
}
|
|
47
55
|
function readImageHeader(data, start, end) {
|
|
48
|
-
|
|
56
|
+
const JP2_IMAGE_HEADER_SIZE = 14;
|
|
57
|
+
const IMAGE_HEADER_COMPONENT_COUNT_OFFSET = 8;
|
|
58
|
+
const IMAGE_HEADER_BIT_DEPTH_OFFSET = 10;
|
|
59
|
+
const IMAGE_HEADER_BPC_VARIES = 255;
|
|
60
|
+
const BPC_DEPTH_MASK = 127;
|
|
61
|
+
const BPC_SIGNED_BIT = 128;
|
|
62
|
+
if (end - start < JP2_IMAGE_HEADER_SIZE) throw new require_image_jpeg2000_errors.Jpeg2000ParseError("the JP2 image header box is shorter than the 14 bytes ISO/IEC 15444-1 I.5.3.1 defines");
|
|
49
63
|
const height = readUint32(data, start);
|
|
50
|
-
const width = readUint32(data, start +
|
|
51
|
-
const componentCount = (data[start +
|
|
52
|
-
const bpc = data[start +
|
|
53
|
-
if (bpc ===
|
|
64
|
+
const width = readUint32(data, start + UINT32_SIZE);
|
|
65
|
+
const componentCount = (data[start + IMAGE_HEADER_COMPONENT_COUNT_OFFSET] ?? 0) << BITS_PER_BYTE | (data[start + IMAGE_HEADER_COMPONENT_COUNT_OFFSET + 1] ?? 0);
|
|
66
|
+
const bpc = data[start + IMAGE_HEADER_BIT_DEPTH_OFFSET] ?? 0;
|
|
67
|
+
if (bpc === IMAGE_HEADER_BPC_VARIES) return {
|
|
54
68
|
width,
|
|
55
69
|
height,
|
|
56
70
|
componentCount
|
|
@@ -59,20 +73,23 @@ function readImageHeader(data, start, end) {
|
|
|
59
73
|
width,
|
|
60
74
|
height,
|
|
61
75
|
componentCount,
|
|
62
|
-
bitDepth: (bpc &
|
|
63
|
-
signed: (bpc &
|
|
76
|
+
bitDepth: (bpc & BPC_DEPTH_MASK) + 1,
|
|
77
|
+
signed: (bpc & BPC_SIGNED_BIT) !== 0
|
|
64
78
|
};
|
|
65
79
|
}
|
|
66
80
|
function readChannelDefinitions(data, start, end) {
|
|
67
|
-
const
|
|
81
|
+
const CHANNEL_DEFINITION_ENTRY_SIZE = 6;
|
|
82
|
+
const CHANNEL_DEFINITION_TYPE_OFFSET = 2;
|
|
83
|
+
const CHANNEL_DEFINITION_ASSOCIATION_OFFSET = 4;
|
|
84
|
+
const count = (data[start] ?? 0) << BITS_PER_BYTE | (data[start + 1] ?? 0);
|
|
68
85
|
const definitions = [];
|
|
69
86
|
for (let i = 0; i < count; i++) {
|
|
70
|
-
const entry = start + 2 + i *
|
|
71
|
-
if (entry +
|
|
87
|
+
const entry = start + 2 + i * CHANNEL_DEFINITION_ENTRY_SIZE;
|
|
88
|
+
if (entry + CHANNEL_DEFINITION_ENTRY_SIZE > end) break;
|
|
72
89
|
definitions.push({
|
|
73
|
-
channel: (data[entry] ?? 0) <<
|
|
74
|
-
type: (data[entry +
|
|
75
|
-
association: (data[entry +
|
|
90
|
+
channel: (data[entry] ?? 0) << BITS_PER_BYTE | (data[entry + 1] ?? 0),
|
|
91
|
+
type: (data[entry + CHANNEL_DEFINITION_TYPE_OFFSET] ?? 0) << BITS_PER_BYTE | (data[entry + CHANNEL_DEFINITION_TYPE_OFFSET + 1] ?? 0),
|
|
92
|
+
association: (data[entry + CHANNEL_DEFINITION_ASSOCIATION_OFFSET] ?? 0) << BITS_PER_BYTE | (data[entry + CHANNEL_DEFINITION_ASSOCIATION_OFFSET + 1] ?? 0)
|
|
76
93
|
});
|
|
77
94
|
}
|
|
78
95
|
return definitions;
|
|
@@ -90,20 +107,28 @@ function readJp2HeaderBox(data, start, end, into) {
|
|
|
90
107
|
}
|
|
91
108
|
}
|
|
92
109
|
function readColourSpecification(data, start, end, into) {
|
|
110
|
+
const COLOUR_SPEC_PAYLOAD_PREFIX_SIZE = 3;
|
|
111
|
+
const JP2_ENUM_CS_CMYK = 12;
|
|
112
|
+
const JP2_ENUM_CS_CIELAB = 14;
|
|
113
|
+
const JP2_ENUM_CS_SRGB = 16;
|
|
114
|
+
const JP2_ENUM_CS_GREYSCALE = 17;
|
|
115
|
+
const JP2_ENUM_CS_SYCC = 18;
|
|
116
|
+
const JP2_ENUM_CS_E_SRGB = 20;
|
|
117
|
+
const JP2_ENUM_CS_ROMMRGB = 24;
|
|
93
118
|
const method = data[start] ?? 0;
|
|
94
119
|
if (method === 1) {
|
|
95
120
|
if (end - start >= 7) into.colourSpace = (/* @__PURE__ */ new Map([
|
|
96
|
-
[
|
|
97
|
-
[
|
|
98
|
-
[
|
|
99
|
-
[
|
|
100
|
-
[
|
|
101
|
-
[
|
|
102
|
-
[
|
|
103
|
-
])).get(readUint32(data, start +
|
|
121
|
+
[JP2_ENUM_CS_CMYK, "cmyk"],
|
|
122
|
+
[JP2_ENUM_CS_CIELAB, "cielab"],
|
|
123
|
+
[JP2_ENUM_CS_SRGB, "srgb"],
|
|
124
|
+
[JP2_ENUM_CS_GREYSCALE, "greyscale"],
|
|
125
|
+
[JP2_ENUM_CS_SYCC, "sycc"],
|
|
126
|
+
[JP2_ENUM_CS_E_SRGB, "e-srgb"],
|
|
127
|
+
[JP2_ENUM_CS_ROMMRGB, "rommrgb"]
|
|
128
|
+
])).get(readUint32(data, start + COLOUR_SPEC_PAYLOAD_PREFIX_SIZE));
|
|
104
129
|
return;
|
|
105
130
|
}
|
|
106
|
-
if (method === 2 && end - start >
|
|
131
|
+
if (method === 2 && end - start > COLOUR_SPEC_PAYLOAD_PREFIX_SIZE) into.iccProfile = data.subarray(start + COLOUR_SPEC_PAYLOAD_PREFIX_SIZE, end);
|
|
107
132
|
}
|
|
108
133
|
function parseJp2Container(data) {
|
|
109
134
|
if (looksLikeBareCodestream(data)) return {
|
package/dist/image/jp2-boxes.js
CHANGED
|
@@ -3,6 +3,11 @@ import { Jpeg2000ParseError, Jpeg2000UnsupportedError } from "./jpeg2000-errors.
|
|
|
3
3
|
const BOX_HEADER_BYTES = 8;
|
|
4
4
|
const BOX_LENGTH_EXTENDED = 1;
|
|
5
5
|
const BOX_LENGTH_TO_END = 0;
|
|
6
|
+
const BITS_PER_BYTE = 8;
|
|
7
|
+
const BYTE_0_MULTIPLIER = 16777216;
|
|
8
|
+
const BYTE_1_SHIFT = 16;
|
|
9
|
+
const UINT32_SIZE = 4;
|
|
10
|
+
const UINT32_LAST_BYTE_OFFSET = 3;
|
|
6
11
|
const BOX_SIGNATURE = 1783636e3;
|
|
7
12
|
const BOX_JP2_HEADER = 1785737832;
|
|
8
13
|
const BOX_IMAGE_HEADER = 1768449138;
|
|
@@ -11,26 +16,29 @@ const BOX_PALETTE = 1885564018;
|
|
|
11
16
|
const BOX_COMPONENT_MAPPING = 1668112752;
|
|
12
17
|
const BOX_CHANNEL_DEFINITION = 1667523942;
|
|
13
18
|
const BOX_CONTIGUOUS_CODESTREAM = 1785737827;
|
|
19
|
+
const JPEG2000_MARKER_PREFIX = 255;
|
|
20
|
+
const JPEG2000_SOC_LOW_BYTE = 79;
|
|
21
|
+
const JPEG2000_SIZ_LOW_BYTE = 81;
|
|
14
22
|
function looksLikeBareCodestream(data) {
|
|
15
|
-
return data[0] ===
|
|
23
|
+
return data[0] === JPEG2000_MARKER_PREFIX && data[1] === JPEG2000_SOC_LOW_BYTE && data[2] === JPEG2000_MARKER_PREFIX && data[3] === JPEG2000_SIZ_LOW_BYTE;
|
|
16
24
|
}
|
|
17
25
|
function readUint32(data, offset) {
|
|
18
26
|
const b0 = data[offset];
|
|
19
27
|
const b1 = data[offset + 1];
|
|
20
28
|
const b2 = data[offset + 2];
|
|
21
|
-
const b3 = data[offset +
|
|
29
|
+
const b3 = data[offset + UINT32_LAST_BYTE_OFFSET];
|
|
22
30
|
if (b0 === void 0 || b1 === void 0 || b2 === void 0 || b3 === void 0) throw new Jpeg2000ParseError("JP2 box structure ended in the middle of a 32-bit field");
|
|
23
|
-
return b0 *
|
|
31
|
+
return b0 * BYTE_0_MULTIPLIER + (b1 << BYTE_1_SHIFT) + (b2 << BITS_PER_BYTE) + b3;
|
|
24
32
|
}
|
|
25
33
|
function readBox(data, offset, limit) {
|
|
26
34
|
if (offset + BOX_HEADER_BYTES > limit) return;
|
|
27
35
|
const declaredLength = readUint32(data, offset);
|
|
28
|
-
const type = readUint32(data, offset +
|
|
36
|
+
const type = readUint32(data, offset + UINT32_SIZE);
|
|
29
37
|
let payloadStart = offset + BOX_HEADER_BYTES;
|
|
30
38
|
let boxEnd;
|
|
31
39
|
if (declaredLength === BOX_LENGTH_EXTENDED) {
|
|
32
40
|
const high = readUint32(data, payloadStart);
|
|
33
|
-
const low = readUint32(data, payloadStart +
|
|
41
|
+
const low = readUint32(data, payloadStart + UINT32_SIZE);
|
|
34
42
|
payloadStart += 8;
|
|
35
43
|
boxEnd = high === 0 ? offset + low : limit;
|
|
36
44
|
} else if (declaredLength === BOX_LENGTH_TO_END) boxEnd = limit;
|
|
@@ -44,12 +52,18 @@ function readBox(data, offset, limit) {
|
|
|
44
52
|
};
|
|
45
53
|
}
|
|
46
54
|
function readImageHeader(data, start, end) {
|
|
47
|
-
|
|
55
|
+
const JP2_IMAGE_HEADER_SIZE = 14;
|
|
56
|
+
const IMAGE_HEADER_COMPONENT_COUNT_OFFSET = 8;
|
|
57
|
+
const IMAGE_HEADER_BIT_DEPTH_OFFSET = 10;
|
|
58
|
+
const IMAGE_HEADER_BPC_VARIES = 255;
|
|
59
|
+
const BPC_DEPTH_MASK = 127;
|
|
60
|
+
const BPC_SIGNED_BIT = 128;
|
|
61
|
+
if (end - start < JP2_IMAGE_HEADER_SIZE) throw new Jpeg2000ParseError("the JP2 image header box is shorter than the 14 bytes ISO/IEC 15444-1 I.5.3.1 defines");
|
|
48
62
|
const height = readUint32(data, start);
|
|
49
|
-
const width = readUint32(data, start +
|
|
50
|
-
const componentCount = (data[start +
|
|
51
|
-
const bpc = data[start +
|
|
52
|
-
if (bpc ===
|
|
63
|
+
const width = readUint32(data, start + UINT32_SIZE);
|
|
64
|
+
const componentCount = (data[start + IMAGE_HEADER_COMPONENT_COUNT_OFFSET] ?? 0) << BITS_PER_BYTE | (data[start + IMAGE_HEADER_COMPONENT_COUNT_OFFSET + 1] ?? 0);
|
|
65
|
+
const bpc = data[start + IMAGE_HEADER_BIT_DEPTH_OFFSET] ?? 0;
|
|
66
|
+
if (bpc === IMAGE_HEADER_BPC_VARIES) return {
|
|
53
67
|
width,
|
|
54
68
|
height,
|
|
55
69
|
componentCount
|
|
@@ -58,20 +72,23 @@ function readImageHeader(data, start, end) {
|
|
|
58
72
|
width,
|
|
59
73
|
height,
|
|
60
74
|
componentCount,
|
|
61
|
-
bitDepth: (bpc &
|
|
62
|
-
signed: (bpc &
|
|
75
|
+
bitDepth: (bpc & BPC_DEPTH_MASK) + 1,
|
|
76
|
+
signed: (bpc & BPC_SIGNED_BIT) !== 0
|
|
63
77
|
};
|
|
64
78
|
}
|
|
65
79
|
function readChannelDefinitions(data, start, end) {
|
|
66
|
-
const
|
|
80
|
+
const CHANNEL_DEFINITION_ENTRY_SIZE = 6;
|
|
81
|
+
const CHANNEL_DEFINITION_TYPE_OFFSET = 2;
|
|
82
|
+
const CHANNEL_DEFINITION_ASSOCIATION_OFFSET = 4;
|
|
83
|
+
const count = (data[start] ?? 0) << BITS_PER_BYTE | (data[start + 1] ?? 0);
|
|
67
84
|
const definitions = [];
|
|
68
85
|
for (let i = 0; i < count; i++) {
|
|
69
|
-
const entry = start + 2 + i *
|
|
70
|
-
if (entry +
|
|
86
|
+
const entry = start + 2 + i * CHANNEL_DEFINITION_ENTRY_SIZE;
|
|
87
|
+
if (entry + CHANNEL_DEFINITION_ENTRY_SIZE > end) break;
|
|
71
88
|
definitions.push({
|
|
72
|
-
channel: (data[entry] ?? 0) <<
|
|
73
|
-
type: (data[entry +
|
|
74
|
-
association: (data[entry +
|
|
89
|
+
channel: (data[entry] ?? 0) << BITS_PER_BYTE | (data[entry + 1] ?? 0),
|
|
90
|
+
type: (data[entry + CHANNEL_DEFINITION_TYPE_OFFSET] ?? 0) << BITS_PER_BYTE | (data[entry + CHANNEL_DEFINITION_TYPE_OFFSET + 1] ?? 0),
|
|
91
|
+
association: (data[entry + CHANNEL_DEFINITION_ASSOCIATION_OFFSET] ?? 0) << BITS_PER_BYTE | (data[entry + CHANNEL_DEFINITION_ASSOCIATION_OFFSET + 1] ?? 0)
|
|
75
92
|
});
|
|
76
93
|
}
|
|
77
94
|
return definitions;
|
|
@@ -89,20 +106,28 @@ function readJp2HeaderBox(data, start, end, into) {
|
|
|
89
106
|
}
|
|
90
107
|
}
|
|
91
108
|
function readColourSpecification(data, start, end, into) {
|
|
109
|
+
const COLOUR_SPEC_PAYLOAD_PREFIX_SIZE = 3;
|
|
110
|
+
const JP2_ENUM_CS_CMYK = 12;
|
|
111
|
+
const JP2_ENUM_CS_CIELAB = 14;
|
|
112
|
+
const JP2_ENUM_CS_SRGB = 16;
|
|
113
|
+
const JP2_ENUM_CS_GREYSCALE = 17;
|
|
114
|
+
const JP2_ENUM_CS_SYCC = 18;
|
|
115
|
+
const JP2_ENUM_CS_E_SRGB = 20;
|
|
116
|
+
const JP2_ENUM_CS_ROMMRGB = 24;
|
|
92
117
|
const method = data[start] ?? 0;
|
|
93
118
|
if (method === 1) {
|
|
94
119
|
if (end - start >= 7) into.colourSpace = (/* @__PURE__ */ new Map([
|
|
95
|
-
[
|
|
96
|
-
[
|
|
97
|
-
[
|
|
98
|
-
[
|
|
99
|
-
[
|
|
100
|
-
[
|
|
101
|
-
[
|
|
102
|
-
])).get(readUint32(data, start +
|
|
120
|
+
[JP2_ENUM_CS_CMYK, "cmyk"],
|
|
121
|
+
[JP2_ENUM_CS_CIELAB, "cielab"],
|
|
122
|
+
[JP2_ENUM_CS_SRGB, "srgb"],
|
|
123
|
+
[JP2_ENUM_CS_GREYSCALE, "greyscale"],
|
|
124
|
+
[JP2_ENUM_CS_SYCC, "sycc"],
|
|
125
|
+
[JP2_ENUM_CS_E_SRGB, "e-srgb"],
|
|
126
|
+
[JP2_ENUM_CS_ROMMRGB, "rommrgb"]
|
|
127
|
+
])).get(readUint32(data, start + COLOUR_SPEC_PAYLOAD_PREFIX_SIZE));
|
|
103
128
|
return;
|
|
104
129
|
}
|
|
105
|
-
if (method === 2 && end - start >
|
|
130
|
+
if (method === 2 && end - start > COLOUR_SPEC_PAYLOAD_PREFIX_SIZE) into.iccProfile = data.subarray(start + COLOUR_SPEC_PAYLOAD_PREFIX_SIZE, end);
|
|
106
131
|
}
|
|
107
132
|
function parseJp2Container(data) {
|
|
108
133
|
if (looksLikeBareCodestream(data)) return {
|
package/dist/image/jpeg-info.cjs
CHANGED
|
@@ -1,63 +1,68 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region src/image/jpeg-info.ts
|
|
3
|
+
const TEM = 1;
|
|
3
4
|
const SOI = 216;
|
|
4
5
|
const EOI = 217;
|
|
5
6
|
const APP14 = 238;
|
|
7
|
+
const SOF0 = 192;
|
|
8
|
+
const SOF1 = 193;
|
|
9
|
+
const SOF2 = 194;
|
|
10
|
+
const SOF9 = 201;
|
|
11
|
+
const SOF10 = 202;
|
|
6
12
|
const SOF_MARKERS = /* @__PURE__ */ new Set([
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
SOF0,
|
|
14
|
+
SOF1,
|
|
15
|
+
SOF2,
|
|
16
|
+
SOF9,
|
|
17
|
+
SOF10
|
|
12
18
|
]);
|
|
13
|
-
const PROGRESSIVE_SOF_MARKERS = /* @__PURE__ */ new Set([
|
|
19
|
+
const PROGRESSIVE_SOF_MARKERS = /* @__PURE__ */ new Set([SOF2, SOF10]);
|
|
20
|
+
const RST0 = 208;
|
|
14
21
|
const NO_PAYLOAD_MARKERS = /* @__PURE__ */ new Set([
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
209,
|
|
20
|
-
210,
|
|
21
|
-
211,
|
|
22
|
-
212,
|
|
23
|
-
213,
|
|
24
|
-
214,
|
|
25
|
-
215
|
|
22
|
+
TEM,
|
|
23
|
+
SOI,
|
|
24
|
+
EOI,
|
|
25
|
+
...Array.from({ length: 8 }, (_, i) => RST0 + i)
|
|
26
26
|
]);
|
|
27
27
|
function requireByte(bytes, index) {
|
|
28
28
|
const value = bytes[index];
|
|
29
29
|
if (value === void 0) throw new Error("unexpected end of JPEG data");
|
|
30
30
|
return value;
|
|
31
31
|
}
|
|
32
|
+
const BITS_PER_BYTE = 8;
|
|
33
|
+
const MARKER_PREFIX = 255;
|
|
32
34
|
function readUint16BE(bytes, offset) {
|
|
33
|
-
return requireByte(bytes, offset) <<
|
|
35
|
+
return requireByte(bytes, offset) << BITS_PER_BYTE | requireByte(bytes, offset + 1);
|
|
34
36
|
}
|
|
35
37
|
function readJpegInfo(bytes) {
|
|
36
|
-
if (requireByte(bytes, 0) !==
|
|
38
|
+
if (requireByte(bytes, 0) !== MARKER_PREFIX || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
|
|
37
39
|
let offset = 2;
|
|
38
40
|
let adobeTransform;
|
|
39
41
|
while (offset < bytes.length) {
|
|
40
|
-
if (bytes[offset] !==
|
|
42
|
+
if (bytes[offset] !== MARKER_PREFIX) {
|
|
41
43
|
offset++;
|
|
42
44
|
continue;
|
|
43
45
|
}
|
|
44
46
|
let markerOffset = offset + 1;
|
|
45
|
-
while (bytes[markerOffset] ===
|
|
47
|
+
while (bytes[markerOffset] === MARKER_PREFIX) markerOffset++;
|
|
46
48
|
const marker = bytes[markerOffset];
|
|
47
49
|
if (marker === void 0) break;
|
|
48
50
|
offset = markerOffset + 1;
|
|
49
51
|
if (marker === EOI) break;
|
|
50
52
|
if (NO_PAYLOAD_MARKERS.has(marker)) continue;
|
|
51
53
|
const segmentLength = readUint16BE(bytes, offset);
|
|
52
|
-
|
|
54
|
+
const APP14_TRANSFORM_OFFSET = 11;
|
|
55
|
+
if (marker === APP14 && segmentLength >= 14) adobeTransform = requireByte(bytes, offset + 2 + APP14_TRANSFORM_OFFSET);
|
|
53
56
|
if (SOF_MARKERS.has(marker)) {
|
|
57
|
+
const SOF_WIDTH_OFFSET = 3;
|
|
58
|
+
const SOF_COMPONENTS_OFFSET = 5;
|
|
54
59
|
const p = offset + 2;
|
|
55
60
|
const precision = requireByte(bytes, p);
|
|
56
61
|
const height = readUint16BE(bytes, p + 1);
|
|
57
62
|
return {
|
|
58
|
-
width: readUint16BE(bytes, p +
|
|
63
|
+
width: readUint16BE(bytes, p + SOF_WIDTH_OFFSET),
|
|
59
64
|
height,
|
|
60
|
-
components: requireByte(bytes, p +
|
|
65
|
+
components: requireByte(bytes, p + SOF_COMPONENTS_OFFSET),
|
|
61
66
|
precision,
|
|
62
67
|
progressive: PROGRESSIVE_SOF_MARKERS.has(marker),
|
|
63
68
|
adobeTransform
|
package/dist/image/jpeg-info.js
CHANGED
|
@@ -1,62 +1,67 @@
|
|
|
1
1
|
//#region src/image/jpeg-info.ts
|
|
2
|
+
const TEM = 1;
|
|
2
3
|
const SOI = 216;
|
|
3
4
|
const EOI = 217;
|
|
4
5
|
const APP14 = 238;
|
|
6
|
+
const SOF0 = 192;
|
|
7
|
+
const SOF1 = 193;
|
|
8
|
+
const SOF2 = 194;
|
|
9
|
+
const SOF9 = 201;
|
|
10
|
+
const SOF10 = 202;
|
|
5
11
|
const SOF_MARKERS = /* @__PURE__ */ new Set([
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
SOF0,
|
|
13
|
+
SOF1,
|
|
14
|
+
SOF2,
|
|
15
|
+
SOF9,
|
|
16
|
+
SOF10
|
|
11
17
|
]);
|
|
12
|
-
const PROGRESSIVE_SOF_MARKERS = /* @__PURE__ */ new Set([
|
|
18
|
+
const PROGRESSIVE_SOF_MARKERS = /* @__PURE__ */ new Set([SOF2, SOF10]);
|
|
19
|
+
const RST0 = 208;
|
|
13
20
|
const NO_PAYLOAD_MARKERS = /* @__PURE__ */ new Set([
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
209,
|
|
19
|
-
210,
|
|
20
|
-
211,
|
|
21
|
-
212,
|
|
22
|
-
213,
|
|
23
|
-
214,
|
|
24
|
-
215
|
|
21
|
+
TEM,
|
|
22
|
+
SOI,
|
|
23
|
+
EOI,
|
|
24
|
+
...Array.from({ length: 8 }, (_, i) => RST0 + i)
|
|
25
25
|
]);
|
|
26
26
|
function requireByte(bytes, index) {
|
|
27
27
|
const value = bytes[index];
|
|
28
28
|
if (value === void 0) throw new Error("unexpected end of JPEG data");
|
|
29
29
|
return value;
|
|
30
30
|
}
|
|
31
|
+
const BITS_PER_BYTE = 8;
|
|
32
|
+
const MARKER_PREFIX = 255;
|
|
31
33
|
function readUint16BE(bytes, offset) {
|
|
32
|
-
return requireByte(bytes, offset) <<
|
|
34
|
+
return requireByte(bytes, offset) << BITS_PER_BYTE | requireByte(bytes, offset + 1);
|
|
33
35
|
}
|
|
34
36
|
function readJpegInfo(bytes) {
|
|
35
|
-
if (requireByte(bytes, 0) !==
|
|
37
|
+
if (requireByte(bytes, 0) !== MARKER_PREFIX || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
|
|
36
38
|
let offset = 2;
|
|
37
39
|
let adobeTransform;
|
|
38
40
|
while (offset < bytes.length) {
|
|
39
|
-
if (bytes[offset] !==
|
|
41
|
+
if (bytes[offset] !== MARKER_PREFIX) {
|
|
40
42
|
offset++;
|
|
41
43
|
continue;
|
|
42
44
|
}
|
|
43
45
|
let markerOffset = offset + 1;
|
|
44
|
-
while (bytes[markerOffset] ===
|
|
46
|
+
while (bytes[markerOffset] === MARKER_PREFIX) markerOffset++;
|
|
45
47
|
const marker = bytes[markerOffset];
|
|
46
48
|
if (marker === void 0) break;
|
|
47
49
|
offset = markerOffset + 1;
|
|
48
50
|
if (marker === EOI) break;
|
|
49
51
|
if (NO_PAYLOAD_MARKERS.has(marker)) continue;
|
|
50
52
|
const segmentLength = readUint16BE(bytes, offset);
|
|
51
|
-
|
|
53
|
+
const APP14_TRANSFORM_OFFSET = 11;
|
|
54
|
+
if (marker === APP14 && segmentLength >= 14) adobeTransform = requireByte(bytes, offset + 2 + APP14_TRANSFORM_OFFSET);
|
|
52
55
|
if (SOF_MARKERS.has(marker)) {
|
|
56
|
+
const SOF_WIDTH_OFFSET = 3;
|
|
57
|
+
const SOF_COMPONENTS_OFFSET = 5;
|
|
53
58
|
const p = offset + 2;
|
|
54
59
|
const precision = requireByte(bytes, p);
|
|
55
60
|
const height = readUint16BE(bytes, p + 1);
|
|
56
61
|
return {
|
|
57
|
-
width: readUint16BE(bytes, p +
|
|
62
|
+
width: readUint16BE(bytes, p + SOF_WIDTH_OFFSET),
|
|
58
63
|
height,
|
|
59
|
-
components: requireByte(bytes, p +
|
|
64
|
+
components: requireByte(bytes, p + SOF_COMPONENTS_OFFSET),
|
|
60
65
|
precision,
|
|
61
66
|
progressive: PROGRESSIVE_SOF_MARKERS.has(marker),
|
|
62
67
|
adobeTransform
|