@poe-platform/safe-bash 0.1.757 → 0.1.758
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/image-ast/index.browser.js +72 -19
- package/dist/image-ast/index.js +72 -19
- package/dist/pdf-ast/ast.d.ts +3 -0
- package/dist/pdf-ast/index.js +88 -36
- package/dist/safe-bash/command-chunks/{chunk-F3J5ZLKF.js → chunk-522TDVLS.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-VFS2MDAB.js → chunk-6YLD37NH.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-YI3GKJ7Q.js → chunk-766IWMTB.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-KSH2F6RG.js → chunk-CUFCNL6G.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-S4MLIYSN.js → chunk-J2NPH7DO.js} +4 -0
- package/dist/safe-bash/command-chunks/{chunk-KBBI4CSU.js → chunk-L2C5TIII.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-H2FQA4OU.js → chunk-TCAGGM44.js} +72 -19
- package/dist/safe-bash/command-chunks/{chunk-WI35236J.js → chunk-XYCWDGOG.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-4F6PG2OT.js → chunk-YJWWRCIG.js} +8 -8
- package/dist/safe-bash-command-column/column.js +3 -3
- package/dist/safe-bash-command-column/index.js +3 -3
- package/dist/safe-bash-command-column/layout.js +2 -2
- package/dist/safe-bash-command-factor/command.js +2 -2
- package/dist/safe-bash-command-factor/index.js +2 -2
- package/dist/safe-bash-command-ffmpeg/index.js +5923 -5893
- package/dist/safe-bash-command-imagemagick/index.js +2 -2
- package/dist/safe-bash-command-pandoc/command.js +3 -3
- package/dist/safe-bash-command-pandoc/index.js +3 -3
- package/dist/safe-bash-command-pdfimages/index.js +72 -19
- package/dist/safe-bash-command-pdfinfo/index.js +88 -36
- package/dist/safe-bash-command-pdftk/index.js +72 -19
- package/dist/safe-bash-command-pdftoppm/index.js +88 -36
- package/dist/safe-bash-command-pdftotext/index.js +72 -19
- package/dist/safe-bash-command-qpdf/index.js +72 -19
- package/dist/safe-bash-command-sips/index.js +2 -2
- package/dist/safe-bash-command-soffice/index.js +2 -2
- package/dist/safe-bash-command-ssconvert/command-bindings.d.ts +18 -0
- package/dist/safe-bash-command-ssconvert/command.d.ts +5 -14
- package/dist/safe-bash-command-ssconvert/commands.d.ts +6 -0
- package/dist/safe-bash-command-ssconvert/commands.js +871 -0
- package/dist/safe-bash-command-ssconvert/core.js +1 -1
- package/dist/safe-bash-command-ssconvert/index.js +269 -209
- package/dist/safe-bash-command-wkhtmltopdf/index.js +72 -19
- package/dist/safe-bash-command-yq/index.js +4 -4
- package/dist/safe-bash-compression-engine/files.js +2 -2
- package/dist/safe-bash-compression-engine/operand.js +4 -4
- package/dist/safe-bash-markdown-engine/commonmark-blocks.js +4 -4
- package/dist/safe-bash-markdown-engine/commonmark-inlines.js +4 -4
- package/dist/safe-bash-markdown-engine/commonmark-syntax.js +2 -2
- package/dist/safe-bash-markdown-engine/gfm-syntax.js +3 -3
- package/dist/safe-bash-markdown-engine/index.js +7 -7
- package/dist/safe-bash-query-engine/index.js +5 -5
- package/dist/safe-bash-query-engine/interpreter.js +4 -4
- package/dist/safe-bash-query-engine/query-core.js +5 -5
- package/package.json +6 -2
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +16 -0
- package/dist/safe-bash/command-chunks/{chunk-OQVIJMBY.js → chunk-7HINP7ZK.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-XAYEDOV5.js → chunk-CG4JSOK2.js} +3 -3
- package/dist/safe-bash/command-chunks/{chunk-YIK4ZYQ4.js → chunk-DC52GWRK.js} +9 -9
- package/dist/safe-bash/command-chunks/{chunk-TOTZFBDT.js → chunk-TKACIO4X.js} +4 -4
- package/dist/safe-bash/command-chunks/{chunk-VTWKS4RM.js → chunk-WF2LSKMI.js} +3 -3
|
@@ -25274,7 +25274,7 @@ var ParsedCosDocument = class {
|
|
|
25274
25274
|
return void 0;
|
|
25275
25275
|
}
|
|
25276
25276
|
};
|
|
25277
|
-
function parseNodeFromLexer(lexer, bytes, maxDepth,
|
|
25277
|
+
function parseNodeFromLexer(lexer, bytes, maxDepth, repair = false) {
|
|
25278
25278
|
const stack = [];
|
|
25279
25279
|
while (true) {
|
|
25280
25280
|
const tok = lexer.nextToken();
|
|
@@ -25283,7 +25283,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
|
|
|
25283
25283
|
if (!parent) return void 0;
|
|
25284
25284
|
throw new PdfError("E_PARSE", parent.kind === "array" ? "Unterminated PDF array" : "Unterminated PDF dictionary");
|
|
25285
25285
|
}
|
|
25286
|
-
if (!parent &&
|
|
25286
|
+
if (!parent && repair && tok.kind === "keyword" && tok.value === "endobj") {
|
|
25287
25287
|
return { kind: "null", span: tok.span };
|
|
25288
25288
|
}
|
|
25289
25289
|
let node;
|
|
@@ -25298,6 +25298,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
|
|
|
25298
25298
|
parent.key = { kind: "name", rawBytes: tok.rawBytes, decoded: tok.decoded, span: tok.span };
|
|
25299
25299
|
continue;
|
|
25300
25300
|
} else {
|
|
25301
|
+
if (repair) continue;
|
|
25301
25302
|
throw new PdfError("E_PARSE", `Expected dictionary key /Name, got ${tok.kind}`);
|
|
25302
25303
|
}
|
|
25303
25304
|
} else {
|
|
@@ -25466,7 +25467,7 @@ function parseHeaderVersion(bytes) {
|
|
|
25466
25467
|
}
|
|
25467
25468
|
return head.slice(idx + 5, idx + 8);
|
|
25468
25469
|
}
|
|
25469
|
-
function parseObjectAtOffset(bytes, offset, maxRecursionDepth,
|
|
25470
|
+
function parseObjectAtOffset(bytes, offset, maxRecursionDepth, repair = false) {
|
|
25470
25471
|
const lexer = new CosByteLexer(bytes, offset);
|
|
25471
25472
|
const objNumTok = lexer.nextToken();
|
|
25472
25473
|
const genNumTok = lexer.nextToken();
|
|
@@ -25474,7 +25475,7 @@ function parseObjectAtOffset(bytes, offset, maxRecursionDepth, recoverEmptyObjec
|
|
|
25474
25475
|
if (objNumTok?.kind !== "number" || genNumTok?.kind !== "number" || objKwTok?.kind !== "keyword" || objKwTok.value !== "obj") {
|
|
25475
25476
|
throw new PdfError("E_PARSE", `Malformed indirect object header at byte offset ${offset}`);
|
|
25476
25477
|
}
|
|
25477
|
-
const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth,
|
|
25478
|
+
const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, repair);
|
|
25478
25479
|
if (!value) {
|
|
25479
25480
|
throw new PdfError("E_PARSE", `Empty indirect object ${objNumTok.value} at offset ${offset}`);
|
|
25480
25481
|
}
|
|
@@ -25663,7 +25664,7 @@ function repairScanCosDocument(bytes, maxObjects, maxRecursionDepth) {
|
|
|
25663
25664
|
try {
|
|
25664
25665
|
const token = lexer.nextToken();
|
|
25665
25666
|
if (token?.kind === "keyword" && token.value === "trailer") {
|
|
25666
|
-
const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth);
|
|
25667
|
+
const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, true);
|
|
25667
25668
|
if (trailer?.kind === "dict") trailers.push(trailer);
|
|
25668
25669
|
pos = lexer.offset;
|
|
25669
25670
|
continue;
|
|
@@ -25719,7 +25720,7 @@ function unpackRecoveredObjects(objects, maxObjects, maxDecompressedBytes, maxRe
|
|
|
25719
25720
|
const t = dictGet(obj.value.dict, "Type");
|
|
25720
25721
|
if (t?.kind === "name" && t.decoded === "ObjStm") {
|
|
25721
25722
|
try {
|
|
25722
|
-
for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth).entries()) {
|
|
25723
|
+
for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth, true).entries()) {
|
|
25723
25724
|
if (!objects.has(unpackedNum)) {
|
|
25724
25725
|
objects.set(unpackedNum, {
|
|
25725
25726
|
objectNumber: unpackedNum,
|
|
@@ -25755,7 +25756,7 @@ function recoveredReferences(objects) {
|
|
|
25755
25756
|
}
|
|
25756
25757
|
return { ...rootRef ? { rootRef } : {}, ...infoRef ? { infoRef } : {} };
|
|
25757
25758
|
}
|
|
25758
|
-
function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth) {
|
|
25759
|
+
function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth, repair = false) {
|
|
25759
25760
|
const nNode = dictGet(streamObj.dict, "N");
|
|
25760
25761
|
const firstNode = dictGet(streamObj.dict, "First");
|
|
25761
25762
|
if (nNode?.kind !== "number" || firstNode?.kind !== "number") {
|
|
@@ -25775,7 +25776,7 @@ function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth)
|
|
|
25775
25776
|
for (const pair of pairs) {
|
|
25776
25777
|
try {
|
|
25777
25778
|
const valLexer = new CosByteLexer(decoded, firstNode.value + pair.relativeOffset);
|
|
25778
|
-
const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth);
|
|
25779
|
+
const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth, repair);
|
|
25779
25780
|
if (node) {
|
|
25780
25781
|
result.set(pair.objectNumber, node);
|
|
25781
25782
|
}
|
|
@@ -25958,7 +25959,7 @@ function parseCosDocument(bytes, options = {}) {
|
|
|
25958
25959
|
if (!unpacked) {
|
|
25959
25960
|
const stmObj = objects.get(entry.objectStreamNumber)?.value;
|
|
25960
25961
|
if (stmObj?.kind === "stream") {
|
|
25961
|
-
unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth);
|
|
25962
|
+
unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth, recovery === "repair");
|
|
25962
25963
|
objStmCache.set(entry.objectStreamNumber, unpacked);
|
|
25963
25964
|
}
|
|
25964
25965
|
}
|
|
@@ -34430,7 +34431,11 @@ function resolvePageFonts(doc, resourcesDict) {
|
|
|
34430
34431
|
let cmap;
|
|
34431
34432
|
const toUniNode = doc.resolve(dictGet(fObj, "ToUnicode"));
|
|
34432
34433
|
if (toUniNode?.kind === "stream") {
|
|
34433
|
-
|
|
34434
|
+
try {
|
|
34435
|
+
cmap = parseToUnicodeCMap(doc.decodeStream(toUniNode));
|
|
34436
|
+
} catch (error) {
|
|
34437
|
+
if (error instanceof PdfError && error.code === "E_LIMIT") throw error;
|
|
34438
|
+
}
|
|
34434
34439
|
}
|
|
34435
34440
|
const encNode = doc.resolve(dictGet(fObj, "Encoding"));
|
|
34436
34441
|
if (encNode?.kind === "dict") {
|
|
@@ -35554,8 +35559,12 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35554
35559
|
const images = [];
|
|
35555
35560
|
const operations = [];
|
|
35556
35561
|
const emit = (operation) => {
|
|
35557
|
-
const clipPaths = curState()
|
|
35558
|
-
if (clipPaths) operation = { ...operation, value: {
|
|
35562
|
+
const { clipPaths, clipImages } = curState();
|
|
35563
|
+
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
35564
|
+
...operation.value,
|
|
35565
|
+
...clipPaths ? { clipPaths } : {},
|
|
35566
|
+
...clipImages ? { clipImages } : {}
|
|
35567
|
+
} };
|
|
35559
35568
|
operations.push(operation);
|
|
35560
35569
|
switch (operation.kind) {
|
|
35561
35570
|
case "path":
|
|
@@ -35819,6 +35828,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35819
35828
|
let hasTextClip = false;
|
|
35820
35829
|
let activeTm = [1, 0, 0, 1, 0, 0];
|
|
35821
35830
|
let activeTlm = [1, 0, 0, 1, 0, 0];
|
|
35831
|
+
const paintImage = (image, patternMask, resources, activeFonts, depth) => {
|
|
35832
|
+
if (!patternMask) {
|
|
35833
|
+
emit({ kind: "image", value: image });
|
|
35834
|
+
return;
|
|
35835
|
+
}
|
|
35836
|
+
const st = curState();
|
|
35837
|
+
stateStack.push({ ...st, clipImages: [...st.clipImages ?? [], image] });
|
|
35838
|
+
walkNodes([{ kind: "path-op", paint: "f", segments: [
|
|
35839
|
+
{ kind: "rect", x: 0, y: 0, width: 1, height: 1 }
|
|
35840
|
+
] }], void 0, void 0, resources, activeFonts, depth);
|
|
35841
|
+
stateStack.pop();
|
|
35842
|
+
};
|
|
35822
35843
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
35823
35844
|
for (const node of nodes) {
|
|
35824
35845
|
switch (node.kind) {
|
|
@@ -36002,7 +36023,8 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36002
36023
|
st.fillAlpha,
|
|
36003
36024
|
"PatternShading_" + st.fillPatternName,
|
|
36004
36025
|
patClip,
|
|
36005
|
-
shading?.kind === "stream" ? shading : void 0
|
|
36026
|
+
shading?.kind === "stream" ? shading : void 0,
|
|
36027
|
+
st.blendMode
|
|
36006
36028
|
);
|
|
36007
36029
|
if (shImg) {
|
|
36008
36030
|
emit({ kind: "image", value: shImg });
|
|
@@ -36111,18 +36133,20 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36111
36133
|
const subNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "Subtype"));
|
|
36112
36134
|
const sub = subNode?.kind === "name" ? subNode.decoded : "";
|
|
36113
36135
|
if (sub === "Image") {
|
|
36136
|
+
const maskNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "ImageMask"));
|
|
36137
|
+
const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
|
|
36114
36138
|
const decoded = decodeXObjectImageToRgba(
|
|
36115
36139
|
params.cosDoc,
|
|
36116
36140
|
xobjNode,
|
|
36117
36141
|
activeResources,
|
|
36118
|
-
{
|
|
36142
|
+
patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
|
|
36119
36143
|
r: st.fillColor.r,
|
|
36120
36144
|
g: st.fillColor.g,
|
|
36121
36145
|
b: st.fillColor.b,
|
|
36122
36146
|
alpha: st.fillAlpha
|
|
36123
36147
|
}
|
|
36124
36148
|
);
|
|
36125
|
-
|
|
36149
|
+
paintImage({
|
|
36126
36150
|
name: node.name,
|
|
36127
36151
|
matrix: [...st.ctm],
|
|
36128
36152
|
width: decoded.width,
|
|
@@ -36132,7 +36156,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36132
36156
|
decodedRgba: decoded.rgba,
|
|
36133
36157
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36134
36158
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36135
|
-
}
|
|
36159
|
+
}, patternMask, activeResources, activeFonts, depth);
|
|
36136
36160
|
} else if (sub === "Form" && depth < 8) {
|
|
36137
36161
|
const formStreamBytes = params.cosDoc.decodeStream(xobjNode);
|
|
36138
36162
|
const formNodes = parseContentStream(formStreamBytes);
|
|
@@ -36188,19 +36212,22 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36188
36212
|
}
|
|
36189
36213
|
case "inline-image": {
|
|
36190
36214
|
const st = curState();
|
|
36215
|
+
const maskEntry = dictGet(node.dict, "ImageMask") ?? dictGet(node.dict, "IM");
|
|
36216
|
+
const maskNode = params.cosDoc ? params.cosDoc.resolve(maskEntry) : maskEntry;
|
|
36217
|
+
const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
|
|
36191
36218
|
const decoded = decodeInlineImageNodeToRgba(
|
|
36192
36219
|
params.cosDoc,
|
|
36193
36220
|
node.dict,
|
|
36194
36221
|
node.data,
|
|
36195
36222
|
activeResources,
|
|
36196
|
-
{
|
|
36223
|
+
patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
|
|
36197
36224
|
r: st.fillColor.r,
|
|
36198
36225
|
g: st.fillColor.g,
|
|
36199
36226
|
b: st.fillColor.b,
|
|
36200
36227
|
alpha: st.fillAlpha
|
|
36201
36228
|
}
|
|
36202
36229
|
);
|
|
36203
|
-
|
|
36230
|
+
paintImage({
|
|
36204
36231
|
name: "InlineImage",
|
|
36205
36232
|
matrix: [...st.ctm],
|
|
36206
36233
|
width: decoded.width,
|
|
@@ -36210,7 +36237,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36210
36237
|
decodedRgba: decoded.rgba,
|
|
36211
36238
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36212
36239
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36213
|
-
}
|
|
36240
|
+
}, patternMask, activeResources, activeFonts, depth);
|
|
36214
36241
|
break;
|
|
36215
36242
|
}
|
|
36216
36243
|
case "text-object": {
|
|
@@ -40124,6 +40151,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40124
40151
|
const aaVec = options.antialiasVector !== false;
|
|
40125
40152
|
const aaTxt = options.antialiasText !== false;
|
|
40126
40153
|
const clipMasks = /* @__PURE__ */ new Map();
|
|
40154
|
+
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
40127
40155
|
for (const original of paintOperations(displayList)) {
|
|
40128
40156
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40129
40157
|
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
@@ -40138,6 +40166,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40138
40166
|
}
|
|
40139
40167
|
clipMasks.set(clips, clipMask);
|
|
40140
40168
|
}
|
|
40169
|
+
const imageClips = original.value.clipImages;
|
|
40170
|
+
if (imageClips) {
|
|
40171
|
+
let imageMask = imageClipMasks.get(imageClips);
|
|
40172
|
+
if (!imageMask) {
|
|
40173
|
+
imageMask = new Uint8Array(width * height * 4).fill(255);
|
|
40174
|
+
for (const image of imageClips) {
|
|
40175
|
+
const layer = renderDisplayListToBitmap({
|
|
40176
|
+
...displayList,
|
|
40177
|
+
rotation: 0,
|
|
40178
|
+
paths: [],
|
|
40179
|
+
glyphs: [],
|
|
40180
|
+
images: [image],
|
|
40181
|
+
operations: [{ kind: "image", value: image }]
|
|
40182
|
+
}, { scale, transparent: true }).data;
|
|
40183
|
+
for (let i = 3; i < layer.length; i += 4) imageMask[i] = Math.round(imageMask[i] * layer[i] / 255);
|
|
40184
|
+
}
|
|
40185
|
+
imageClipMasks.set(imageClips, imageMask);
|
|
40186
|
+
}
|
|
40187
|
+
if (clipMask) {
|
|
40188
|
+
clipMask = clipMask.slice();
|
|
40189
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * imageMask[i] / 255);
|
|
40190
|
+
} else {
|
|
40191
|
+
clipMask = imageMask;
|
|
40192
|
+
}
|
|
40193
|
+
}
|
|
40141
40194
|
if (operation.kind === "path") {
|
|
40142
40195
|
const path = operation.value;
|
|
40143
40196
|
if (path.fillColor) {
|
|
@@ -25468,7 +25468,7 @@ var ParsedCosDocument = class {
|
|
|
25468
25468
|
return void 0;
|
|
25469
25469
|
}
|
|
25470
25470
|
};
|
|
25471
|
-
function parseNodeFromLexer(lexer, bytes, maxDepth,
|
|
25471
|
+
function parseNodeFromLexer(lexer, bytes, maxDepth, repair = false) {
|
|
25472
25472
|
const stack = [];
|
|
25473
25473
|
while (true) {
|
|
25474
25474
|
const tok = lexer.nextToken();
|
|
@@ -25477,7 +25477,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
|
|
|
25477
25477
|
if (!parent) return void 0;
|
|
25478
25478
|
throw new PdfError("E_PARSE", parent.kind === "array" ? "Unterminated PDF array" : "Unterminated PDF dictionary");
|
|
25479
25479
|
}
|
|
25480
|
-
if (!parent &&
|
|
25480
|
+
if (!parent && repair && tok.kind === "keyword" && tok.value === "endobj") {
|
|
25481
25481
|
return { kind: "null", span: tok.span };
|
|
25482
25482
|
}
|
|
25483
25483
|
let node;
|
|
@@ -25492,6 +25492,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
|
|
|
25492
25492
|
parent.key = { kind: "name", rawBytes: tok.rawBytes, decoded: tok.decoded, span: tok.span };
|
|
25493
25493
|
continue;
|
|
25494
25494
|
} else {
|
|
25495
|
+
if (repair) continue;
|
|
25495
25496
|
throw new PdfError("E_PARSE", `Expected dictionary key /Name, got ${tok.kind}`);
|
|
25496
25497
|
}
|
|
25497
25498
|
} else {
|
|
@@ -25660,7 +25661,7 @@ function parseHeaderVersion(bytes) {
|
|
|
25660
25661
|
}
|
|
25661
25662
|
return head.slice(idx + 5, idx + 8);
|
|
25662
25663
|
}
|
|
25663
|
-
function parseObjectAtOffset(bytes, offset, maxRecursionDepth,
|
|
25664
|
+
function parseObjectAtOffset(bytes, offset, maxRecursionDepth, repair = false) {
|
|
25664
25665
|
const lexer = new CosByteLexer(bytes, offset);
|
|
25665
25666
|
const objNumTok = lexer.nextToken();
|
|
25666
25667
|
const genNumTok = lexer.nextToken();
|
|
@@ -25668,7 +25669,7 @@ function parseObjectAtOffset(bytes, offset, maxRecursionDepth, recoverEmptyObjec
|
|
|
25668
25669
|
if (objNumTok?.kind !== "number" || genNumTok?.kind !== "number" || objKwTok?.kind !== "keyword" || objKwTok.value !== "obj") {
|
|
25669
25670
|
throw new PdfError("E_PARSE", `Malformed indirect object header at byte offset ${offset}`);
|
|
25670
25671
|
}
|
|
25671
|
-
const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth,
|
|
25672
|
+
const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, repair);
|
|
25672
25673
|
if (!value) {
|
|
25673
25674
|
throw new PdfError("E_PARSE", `Empty indirect object ${objNumTok.value} at offset ${offset}`);
|
|
25674
25675
|
}
|
|
@@ -25857,7 +25858,7 @@ function repairScanCosDocument(bytes, maxObjects, maxRecursionDepth) {
|
|
|
25857
25858
|
try {
|
|
25858
25859
|
const token = lexer.nextToken();
|
|
25859
25860
|
if (token?.kind === "keyword" && token.value === "trailer") {
|
|
25860
|
-
const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth);
|
|
25861
|
+
const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, true);
|
|
25861
25862
|
if (trailer?.kind === "dict") trailers.push(trailer);
|
|
25862
25863
|
pos = lexer.offset;
|
|
25863
25864
|
continue;
|
|
@@ -25913,7 +25914,7 @@ function unpackRecoveredObjects(objects, maxObjects, maxDecompressedBytes, maxRe
|
|
|
25913
25914
|
const t = dictGet(obj.value.dict, "Type");
|
|
25914
25915
|
if (t?.kind === "name" && t.decoded === "ObjStm") {
|
|
25915
25916
|
try {
|
|
25916
|
-
for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth).entries()) {
|
|
25917
|
+
for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth, true).entries()) {
|
|
25917
25918
|
if (!objects.has(unpackedNum)) {
|
|
25918
25919
|
objects.set(unpackedNum, {
|
|
25919
25920
|
objectNumber: unpackedNum,
|
|
@@ -25949,7 +25950,7 @@ function recoveredReferences(objects) {
|
|
|
25949
25950
|
}
|
|
25950
25951
|
return { ...rootRef ? { rootRef } : {}, ...infoRef ? { infoRef } : {} };
|
|
25951
25952
|
}
|
|
25952
|
-
function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth) {
|
|
25953
|
+
function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth, repair = false) {
|
|
25953
25954
|
const nNode = dictGet(streamObj.dict, "N");
|
|
25954
25955
|
const firstNode = dictGet(streamObj.dict, "First");
|
|
25955
25956
|
if (nNode?.kind !== "number" || firstNode?.kind !== "number") {
|
|
@@ -25969,7 +25970,7 @@ function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth)
|
|
|
25969
25970
|
for (const pair of pairs) {
|
|
25970
25971
|
try {
|
|
25971
25972
|
const valLexer = new CosByteLexer(decoded, firstNode.value + pair.relativeOffset);
|
|
25972
|
-
const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth);
|
|
25973
|
+
const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth, repair);
|
|
25973
25974
|
if (node) {
|
|
25974
25975
|
result.set(pair.objectNumber, node);
|
|
25975
25976
|
}
|
|
@@ -26152,7 +26153,7 @@ function parseCosDocument(bytes, options = {}) {
|
|
|
26152
26153
|
if (!unpacked) {
|
|
26153
26154
|
const stmObj = objects.get(entry.objectStreamNumber)?.value;
|
|
26154
26155
|
if (stmObj?.kind === "stream") {
|
|
26155
|
-
unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth);
|
|
26156
|
+
unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth, recovery === "repair");
|
|
26156
26157
|
objStmCache.set(entry.objectStreamNumber, unpacked);
|
|
26157
26158
|
}
|
|
26158
26159
|
}
|
|
@@ -34624,7 +34625,11 @@ function resolvePageFonts(doc, resourcesDict) {
|
|
|
34624
34625
|
let cmap;
|
|
34625
34626
|
const toUniNode = doc.resolve(dictGet(fObj, "ToUnicode"));
|
|
34626
34627
|
if (toUniNode?.kind === "stream") {
|
|
34627
|
-
|
|
34628
|
+
try {
|
|
34629
|
+
cmap = parseToUnicodeCMap(doc.decodeStream(toUniNode));
|
|
34630
|
+
} catch (error) {
|
|
34631
|
+
if (error instanceof PdfError && error.code === "E_LIMIT") throw error;
|
|
34632
|
+
}
|
|
34628
34633
|
}
|
|
34629
34634
|
const encNode = doc.resolve(dictGet(fObj, "Encoding"));
|
|
34630
34635
|
if (encNode?.kind === "dict") {
|
|
@@ -35748,8 +35753,12 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35748
35753
|
const images = [];
|
|
35749
35754
|
const operations = [];
|
|
35750
35755
|
const emit = (operation) => {
|
|
35751
|
-
const clipPaths = curState()
|
|
35752
|
-
if (clipPaths) operation = { ...operation, value: {
|
|
35756
|
+
const { clipPaths, clipImages } = curState();
|
|
35757
|
+
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
35758
|
+
...operation.value,
|
|
35759
|
+
...clipPaths ? { clipPaths } : {},
|
|
35760
|
+
...clipImages ? { clipImages } : {}
|
|
35761
|
+
} };
|
|
35753
35762
|
operations.push(operation);
|
|
35754
35763
|
switch (operation.kind) {
|
|
35755
35764
|
case "path":
|
|
@@ -36013,6 +36022,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36013
36022
|
let hasTextClip = false;
|
|
36014
36023
|
let activeTm = [1, 0, 0, 1, 0, 0];
|
|
36015
36024
|
let activeTlm = [1, 0, 0, 1, 0, 0];
|
|
36025
|
+
const paintImage = (image, patternMask, resources, activeFonts, depth) => {
|
|
36026
|
+
if (!patternMask) {
|
|
36027
|
+
emit({ kind: "image", value: image });
|
|
36028
|
+
return;
|
|
36029
|
+
}
|
|
36030
|
+
const st = curState();
|
|
36031
|
+
stateStack.push({ ...st, clipImages: [...st.clipImages ?? [], image] });
|
|
36032
|
+
walkNodes([{ kind: "path-op", paint: "f", segments: [
|
|
36033
|
+
{ kind: "rect", x: 0, y: 0, width: 1, height: 1 }
|
|
36034
|
+
] }], void 0, void 0, resources, activeFonts, depth);
|
|
36035
|
+
stateStack.pop();
|
|
36036
|
+
};
|
|
36016
36037
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36017
36038
|
for (const node of nodes) {
|
|
36018
36039
|
switch (node.kind) {
|
|
@@ -36196,7 +36217,8 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36196
36217
|
st.fillAlpha,
|
|
36197
36218
|
"PatternShading_" + st.fillPatternName,
|
|
36198
36219
|
patClip,
|
|
36199
|
-
shading?.kind === "stream" ? shading : void 0
|
|
36220
|
+
shading?.kind === "stream" ? shading : void 0,
|
|
36221
|
+
st.blendMode
|
|
36200
36222
|
);
|
|
36201
36223
|
if (shImg) {
|
|
36202
36224
|
emit({ kind: "image", value: shImg });
|
|
@@ -36305,18 +36327,20 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36305
36327
|
const subNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "Subtype"));
|
|
36306
36328
|
const sub = subNode?.kind === "name" ? subNode.decoded : "";
|
|
36307
36329
|
if (sub === "Image") {
|
|
36330
|
+
const maskNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "ImageMask"));
|
|
36331
|
+
const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
|
|
36308
36332
|
const decoded = decodeXObjectImageToRgba(
|
|
36309
36333
|
params.cosDoc,
|
|
36310
36334
|
xobjNode,
|
|
36311
36335
|
activeResources,
|
|
36312
|
-
{
|
|
36336
|
+
patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
|
|
36313
36337
|
r: st.fillColor.r,
|
|
36314
36338
|
g: st.fillColor.g,
|
|
36315
36339
|
b: st.fillColor.b,
|
|
36316
36340
|
alpha: st.fillAlpha
|
|
36317
36341
|
}
|
|
36318
36342
|
);
|
|
36319
|
-
|
|
36343
|
+
paintImage({
|
|
36320
36344
|
name: node.name,
|
|
36321
36345
|
matrix: [...st.ctm],
|
|
36322
36346
|
width: decoded.width,
|
|
@@ -36326,7 +36350,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36326
36350
|
decodedRgba: decoded.rgba,
|
|
36327
36351
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36328
36352
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36329
|
-
}
|
|
36353
|
+
}, patternMask, activeResources, activeFonts, depth);
|
|
36330
36354
|
} else if (sub === "Form" && depth < 8) {
|
|
36331
36355
|
const formStreamBytes = params.cosDoc.decodeStream(xobjNode);
|
|
36332
36356
|
const formNodes = parseContentStream(formStreamBytes);
|
|
@@ -36382,19 +36406,22 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36382
36406
|
}
|
|
36383
36407
|
case "inline-image": {
|
|
36384
36408
|
const st = curState();
|
|
36409
|
+
const maskEntry = dictGet(node.dict, "ImageMask") ?? dictGet(node.dict, "IM");
|
|
36410
|
+
const maskNode = params.cosDoc ? params.cosDoc.resolve(maskEntry) : maskEntry;
|
|
36411
|
+
const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
|
|
36385
36412
|
const decoded = decodeInlineImageNodeToRgba(
|
|
36386
36413
|
params.cosDoc,
|
|
36387
36414
|
node.dict,
|
|
36388
36415
|
node.data,
|
|
36389
36416
|
activeResources,
|
|
36390
|
-
{
|
|
36417
|
+
patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
|
|
36391
36418
|
r: st.fillColor.r,
|
|
36392
36419
|
g: st.fillColor.g,
|
|
36393
36420
|
b: st.fillColor.b,
|
|
36394
36421
|
alpha: st.fillAlpha
|
|
36395
36422
|
}
|
|
36396
36423
|
);
|
|
36397
|
-
|
|
36424
|
+
paintImage({
|
|
36398
36425
|
name: "InlineImage",
|
|
36399
36426
|
matrix: [...st.ctm],
|
|
36400
36427
|
width: decoded.width,
|
|
@@ -36404,7 +36431,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36404
36431
|
decodedRgba: decoded.rgba,
|
|
36405
36432
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36406
36433
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36407
|
-
}
|
|
36434
|
+
}, patternMask, activeResources, activeFonts, depth);
|
|
36408
36435
|
break;
|
|
36409
36436
|
}
|
|
36410
36437
|
case "text-object": {
|
|
@@ -40150,6 +40177,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40150
40177
|
const aaVec = options.antialiasVector !== false;
|
|
40151
40178
|
const aaTxt = options.antialiasText !== false;
|
|
40152
40179
|
const clipMasks = /* @__PURE__ */ new Map();
|
|
40180
|
+
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
40153
40181
|
for (const original of paintOperations(displayList)) {
|
|
40154
40182
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40155
40183
|
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
@@ -40164,6 +40192,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40164
40192
|
}
|
|
40165
40193
|
clipMasks.set(clips, clipMask);
|
|
40166
40194
|
}
|
|
40195
|
+
const imageClips = original.value.clipImages;
|
|
40196
|
+
if (imageClips) {
|
|
40197
|
+
let imageMask = imageClipMasks.get(imageClips);
|
|
40198
|
+
if (!imageMask) {
|
|
40199
|
+
imageMask = new Uint8Array(width * height * 4).fill(255);
|
|
40200
|
+
for (const image of imageClips) {
|
|
40201
|
+
const layer = renderDisplayListToBitmap({
|
|
40202
|
+
...displayList,
|
|
40203
|
+
rotation: 0,
|
|
40204
|
+
paths: [],
|
|
40205
|
+
glyphs: [],
|
|
40206
|
+
images: [image],
|
|
40207
|
+
operations: [{ kind: "image", value: image }]
|
|
40208
|
+
}, { scale, transparent: true }).data;
|
|
40209
|
+
for (let i = 3; i < layer.length; i += 4) imageMask[i] = Math.round(imageMask[i] * layer[i] / 255);
|
|
40210
|
+
}
|
|
40211
|
+
imageClipMasks.set(imageClips, imageMask);
|
|
40212
|
+
}
|
|
40213
|
+
if (clipMask) {
|
|
40214
|
+
clipMask = clipMask.slice();
|
|
40215
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * imageMask[i] / 255);
|
|
40216
|
+
} else {
|
|
40217
|
+
clipMask = imageMask;
|
|
40218
|
+
}
|
|
40219
|
+
}
|
|
40167
40220
|
if (operation.kind === "path") {
|
|
40168
40221
|
const path = operation.value;
|
|
40169
40222
|
if (path.fillColor) {
|
|
@@ -40312,6 +40365,15 @@ function escapeXmlText(str) {
|
|
|
40312
40365
|
}
|
|
40313
40366
|
return encodeToXmlString(valid);
|
|
40314
40367
|
}
|
|
40368
|
+
function svgImage(image, pageHeight) {
|
|
40369
|
+
if (!image.decodedRgba) return "";
|
|
40370
|
+
const png = encodeRgbaToPng(image.width, image.height, image.decodedRgba);
|
|
40371
|
+
const chunks = [];
|
|
40372
|
+
for (let offset = 0; offset < png.length; offset += 8192)
|
|
40373
|
+
chunks.push(String.fromCharCode(...png.subarray(offset, offset + 8192)));
|
|
40374
|
+
const [a, b, c, d, e, f] = image.matrix;
|
|
40375
|
+
return `<image width="1" height="1" preserveAspectRatio="none" transform="matrix(${a} ${-b} ${-c} ${d} ${e + c} ${pageHeight - f - d})" href="data:image/png;base64,${btoa(chunks.join(""))}"/>`;
|
|
40376
|
+
}
|
|
40315
40377
|
function svgPathData(segments, height) {
|
|
40316
40378
|
const dParts = [];
|
|
40317
40379
|
for (const seg of segments) {
|
|
@@ -40360,11 +40422,16 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40360
40422
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40361
40423
|
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
40362
40424
|
const clips = original.value.clipPaths ?? [];
|
|
40425
|
+
const imageClips = original.value.clipImages ?? [];
|
|
40363
40426
|
for (const segments of clips) {
|
|
40364
40427
|
const id = `text-clip-${clipId++}`;
|
|
40365
40428
|
const path = `<path d="${svgPathData(segments, displayList.height)}"/>`;
|
|
40366
40429
|
parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
|
|
40367
40430
|
}
|
|
40431
|
+
for (const image of imageClips) {
|
|
40432
|
+
const id = `image-clip-${clipId++}`;
|
|
40433
|
+
parts.push(`<defs><mask id="${id}" maskUnits="userSpaceOnUse" x="0" y="0" width="${displayList.width}" height="${displayList.height}" style="mask-type:alpha">${svgImage(image, displayList.height)}</mask></defs><g mask="url(#${id})">`);
|
|
40434
|
+
}
|
|
40368
40435
|
if (operation.kind === "path") {
|
|
40369
40436
|
const p = operation.value;
|
|
40370
40437
|
const pathData = svgPathData(p.segments, displayList.height);
|
|
@@ -40384,24 +40451,9 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40384
40451
|
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
40385
40452
|
}
|
|
40386
40453
|
} else if (operation.kind === "image") {
|
|
40387
|
-
|
|
40388
|
-
if (!img.decodedRgba) {
|
|
40389
|
-
for (let i = 0; i < clips.length; i++) parts.push("</g>");
|
|
40390
|
-
continue;
|
|
40391
|
-
}
|
|
40392
|
-
const pngBytes = encodeRgbaToPng(img.width, img.height, img.decodedRgba);
|
|
40393
|
-
const chunks = [];
|
|
40394
|
-
for (let offset = 0; offset < pngBytes.length; offset += 8192)
|
|
40395
|
-
chunks.push(String.fromCharCode(...pngBytes.subarray(offset, offset + 8192)));
|
|
40396
|
-
const b64 = btoa(chunks.join(""));
|
|
40397
|
-
const [a, b, c, d, e, f] = img.matrix;
|
|
40398
|
-
const svgTx = e + c;
|
|
40399
|
-
const svgTy = displayList.height - f - d;
|
|
40400
|
-
parts.push(
|
|
40401
|
-
` <image width="1" height="1" preserveAspectRatio="none" transform="matrix(${a} ${-b} ${-c} ${d} ${svgTx} ${svgTy})" href="data:image/png;base64,${b64}"/>`
|
|
40402
|
-
);
|
|
40454
|
+
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
40403
40455
|
}
|
|
40404
|
-
for (let i = 0; i < clips.length; i++) parts.push("</g>");
|
|
40456
|
+
for (let i = 0; i < clips.length + imageClips.length; i++) parts.push("</g>");
|
|
40405
40457
|
}
|
|
40406
40458
|
if (displayList.rotation) parts.push("</g>");
|
|
40407
40459
|
parts.push("</svg>\n");
|