@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.
Files changed (55) hide show
  1. package/dist/image-ast/index.browser.js +72 -19
  2. package/dist/image-ast/index.js +72 -19
  3. package/dist/pdf-ast/ast.d.ts +3 -0
  4. package/dist/pdf-ast/index.js +88 -36
  5. package/dist/safe-bash/command-chunks/{chunk-F3J5ZLKF.js → chunk-522TDVLS.js} +1 -1
  6. package/dist/safe-bash/command-chunks/{chunk-VFS2MDAB.js → chunk-6YLD37NH.js} +2 -2
  7. package/dist/safe-bash/command-chunks/{chunk-YI3GKJ7Q.js → chunk-766IWMTB.js} +2 -2
  8. package/dist/safe-bash/command-chunks/{chunk-KSH2F6RG.js → chunk-CUFCNL6G.js} +1 -1
  9. package/dist/safe-bash/command-chunks/{chunk-S4MLIYSN.js → chunk-J2NPH7DO.js} +4 -0
  10. package/dist/safe-bash/command-chunks/{chunk-KBBI4CSU.js → chunk-L2C5TIII.js} +2 -2
  11. package/dist/safe-bash/command-chunks/{chunk-H2FQA4OU.js → chunk-TCAGGM44.js} +72 -19
  12. package/dist/safe-bash/command-chunks/{chunk-WI35236J.js → chunk-XYCWDGOG.js} +1 -1
  13. package/dist/safe-bash/command-chunks/{chunk-4F6PG2OT.js → chunk-YJWWRCIG.js} +8 -8
  14. package/dist/safe-bash-command-column/column.js +3 -3
  15. package/dist/safe-bash-command-column/index.js +3 -3
  16. package/dist/safe-bash-command-column/layout.js +2 -2
  17. package/dist/safe-bash-command-factor/command.js +2 -2
  18. package/dist/safe-bash-command-factor/index.js +2 -2
  19. package/dist/safe-bash-command-ffmpeg/index.js +5923 -5893
  20. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  21. package/dist/safe-bash-command-pandoc/command.js +3 -3
  22. package/dist/safe-bash-command-pandoc/index.js +3 -3
  23. package/dist/safe-bash-command-pdfimages/index.js +72 -19
  24. package/dist/safe-bash-command-pdfinfo/index.js +88 -36
  25. package/dist/safe-bash-command-pdftk/index.js +72 -19
  26. package/dist/safe-bash-command-pdftoppm/index.js +88 -36
  27. package/dist/safe-bash-command-pdftotext/index.js +72 -19
  28. package/dist/safe-bash-command-qpdf/index.js +72 -19
  29. package/dist/safe-bash-command-sips/index.js +2 -2
  30. package/dist/safe-bash-command-soffice/index.js +2 -2
  31. package/dist/safe-bash-command-ssconvert/command-bindings.d.ts +18 -0
  32. package/dist/safe-bash-command-ssconvert/command.d.ts +5 -14
  33. package/dist/safe-bash-command-ssconvert/commands.d.ts +6 -0
  34. package/dist/safe-bash-command-ssconvert/commands.js +871 -0
  35. package/dist/safe-bash-command-ssconvert/core.js +1 -1
  36. package/dist/safe-bash-command-ssconvert/index.js +269 -209
  37. package/dist/safe-bash-command-wkhtmltopdf/index.js +72 -19
  38. package/dist/safe-bash-command-yq/index.js +4 -4
  39. package/dist/safe-bash-compression-engine/files.js +2 -2
  40. package/dist/safe-bash-compression-engine/operand.js +4 -4
  41. package/dist/safe-bash-markdown-engine/commonmark-blocks.js +4 -4
  42. package/dist/safe-bash-markdown-engine/commonmark-inlines.js +4 -4
  43. package/dist/safe-bash-markdown-engine/commonmark-syntax.js +2 -2
  44. package/dist/safe-bash-markdown-engine/gfm-syntax.js +3 -3
  45. package/dist/safe-bash-markdown-engine/index.js +7 -7
  46. package/dist/safe-bash-query-engine/index.js +5 -5
  47. package/dist/safe-bash-query-engine/interpreter.js +4 -4
  48. package/dist/safe-bash-query-engine/query-core.js +5 -5
  49. package/package.json +6 -2
  50. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +16 -0
  51. package/dist/safe-bash/command-chunks/{chunk-OQVIJMBY.js → chunk-7HINP7ZK.js} +4 -4
  52. package/dist/safe-bash/command-chunks/{chunk-XAYEDOV5.js → chunk-CG4JSOK2.js} +3 -3
  53. package/dist/safe-bash/command-chunks/{chunk-YIK4ZYQ4.js → chunk-DC52GWRK.js} +9 -9
  54. package/dist/safe-bash/command-chunks/{chunk-TOTZFBDT.js → chunk-TKACIO4X.js} +4 -4
  55. package/dist/safe-bash/command-chunks/{chunk-VTWKS4RM.js → chunk-WF2LSKMI.js} +3 -3
@@ -25603,7 +25603,7 @@ var ParsedCosDocument = class {
25603
25603
  return void 0;
25604
25604
  }
25605
25605
  };
25606
- function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false) {
25606
+ function parseNodeFromLexer(lexer, bytes, maxDepth, repair = false) {
25607
25607
  const stack = [];
25608
25608
  while (true) {
25609
25609
  const tok = lexer.nextToken();
@@ -25612,7 +25612,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
25612
25612
  if (!parent) return void 0;
25613
25613
  throw new PdfError("E_PARSE", parent.kind === "array" ? "Unterminated PDF array" : "Unterminated PDF dictionary");
25614
25614
  }
25615
- if (!parent && recoverEmptyObject && tok.kind === "keyword" && tok.value === "endobj") {
25615
+ if (!parent && repair && tok.kind === "keyword" && tok.value === "endobj") {
25616
25616
  return { kind: "null", span: tok.span };
25617
25617
  }
25618
25618
  let node;
@@ -25627,6 +25627,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
25627
25627
  parent.key = { kind: "name", rawBytes: tok.rawBytes, decoded: tok.decoded, span: tok.span };
25628
25628
  continue;
25629
25629
  } else {
25630
+ if (repair) continue;
25630
25631
  throw new PdfError("E_PARSE", `Expected dictionary key /Name, got ${tok.kind}`);
25631
25632
  }
25632
25633
  } else {
@@ -25795,7 +25796,7 @@ function parseHeaderVersion(bytes) {
25795
25796
  }
25796
25797
  return head.slice(idx + 5, idx + 8);
25797
25798
  }
25798
- function parseObjectAtOffset(bytes, offset, maxRecursionDepth, recoverEmptyObject = false) {
25799
+ function parseObjectAtOffset(bytes, offset, maxRecursionDepth, repair = false) {
25799
25800
  const lexer = new CosByteLexer(bytes, offset);
25800
25801
  const objNumTok = lexer.nextToken();
25801
25802
  const genNumTok = lexer.nextToken();
@@ -25803,7 +25804,7 @@ function parseObjectAtOffset(bytes, offset, maxRecursionDepth, recoverEmptyObjec
25803
25804
  if (objNumTok?.kind !== "number" || genNumTok?.kind !== "number" || objKwTok?.kind !== "keyword" || objKwTok.value !== "obj") {
25804
25805
  throw new PdfError("E_PARSE", `Malformed indirect object header at byte offset ${offset}`);
25805
25806
  }
25806
- const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, recoverEmptyObject);
25807
+ const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, repair);
25807
25808
  if (!value) {
25808
25809
  throw new PdfError("E_PARSE", `Empty indirect object ${objNumTok.value} at offset ${offset}`);
25809
25810
  }
@@ -25992,7 +25993,7 @@ function repairScanCosDocument(bytes, maxObjects, maxRecursionDepth) {
25992
25993
  try {
25993
25994
  const token = lexer.nextToken();
25994
25995
  if (token?.kind === "keyword" && token.value === "trailer") {
25995
- const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth);
25996
+ const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, true);
25996
25997
  if (trailer?.kind === "dict") trailers.push(trailer);
25997
25998
  pos = lexer.offset;
25998
25999
  continue;
@@ -26048,7 +26049,7 @@ function unpackRecoveredObjects(objects, maxObjects, maxDecompressedBytes, maxRe
26048
26049
  const t = dictGet(obj.value.dict, "Type");
26049
26050
  if (t?.kind === "name" && t.decoded === "ObjStm") {
26050
26051
  try {
26051
- for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth).entries()) {
26052
+ for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth, true).entries()) {
26052
26053
  if (!objects.has(unpackedNum)) {
26053
26054
  objects.set(unpackedNum, {
26054
26055
  objectNumber: unpackedNum,
@@ -26084,7 +26085,7 @@ function recoveredReferences(objects) {
26084
26085
  }
26085
26086
  return { ...rootRef ? { rootRef } : {}, ...infoRef ? { infoRef } : {} };
26086
26087
  }
26087
- function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth) {
26088
+ function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth, repair = false) {
26088
26089
  const nNode = dictGet(streamObj.dict, "N");
26089
26090
  const firstNode = dictGet(streamObj.dict, "First");
26090
26091
  if (nNode?.kind !== "number" || firstNode?.kind !== "number") {
@@ -26104,7 +26105,7 @@ function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth)
26104
26105
  for (const pair of pairs) {
26105
26106
  try {
26106
26107
  const valLexer = new CosByteLexer(decoded, firstNode.value + pair.relativeOffset);
26107
- const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth);
26108
+ const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth, repair);
26108
26109
  if (node) {
26109
26110
  result.set(pair.objectNumber, node);
26110
26111
  }
@@ -26287,7 +26288,7 @@ function parseCosDocument(bytes, options = {}) {
26287
26288
  if (!unpacked) {
26288
26289
  const stmObj = objects.get(entry.objectStreamNumber)?.value;
26289
26290
  if (stmObj?.kind === "stream") {
26290
- unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth);
26291
+ unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth, recovery === "repair");
26291
26292
  objStmCache.set(entry.objectStreamNumber, unpacked);
26292
26293
  }
26293
26294
  }
@@ -35143,7 +35144,11 @@ function resolvePageFonts(doc, resourcesDict) {
35143
35144
  let cmap;
35144
35145
  const toUniNode = doc.resolve(dictGet(fObj, "ToUnicode"));
35145
35146
  if (toUniNode?.kind === "stream") {
35146
- cmap = parseToUnicodeCMap(doc.decodeStream(toUniNode));
35147
+ try {
35148
+ cmap = parseToUnicodeCMap(doc.decodeStream(toUniNode));
35149
+ } catch (error) {
35150
+ if (error instanceof PdfError && error.code === "E_LIMIT") throw error;
35151
+ }
35147
35152
  }
35148
35153
  const encNode = doc.resolve(dictGet(fObj, "Encoding"));
35149
35154
  if (encNode?.kind === "dict") {
@@ -36267,8 +36272,12 @@ function evaluateContentStreamToDisplayList(params) {
36267
36272
  const images = [];
36268
36273
  const operations = [];
36269
36274
  const emit = (operation) => {
36270
- const clipPaths = curState().clipPaths;
36271
- if (clipPaths) operation = { ...operation, value: { ...operation.value, clipPaths } };
36275
+ const { clipPaths, clipImages } = curState();
36276
+ if (clipPaths || clipImages) operation = { ...operation, value: {
36277
+ ...operation.value,
36278
+ ...clipPaths ? { clipPaths } : {},
36279
+ ...clipImages ? { clipImages } : {}
36280
+ } };
36272
36281
  operations.push(operation);
36273
36282
  switch (operation.kind) {
36274
36283
  case "path":
@@ -36532,6 +36541,18 @@ function evaluateContentStreamToDisplayList(params) {
36532
36541
  let hasTextClip = false;
36533
36542
  let activeTm = [1, 0, 0, 1, 0, 0];
36534
36543
  let activeTlm = [1, 0, 0, 1, 0, 0];
36544
+ const paintImage = (image, patternMask, resources, activeFonts, depth) => {
36545
+ if (!patternMask) {
36546
+ emit({ kind: "image", value: image });
36547
+ return;
36548
+ }
36549
+ const st = curState();
36550
+ stateStack.push({ ...st, clipImages: [...st.clipImages ?? [], image] });
36551
+ walkNodes([{ kind: "path-op", paint: "f", segments: [
36552
+ { kind: "rect", x: 0, y: 0, width: 1, height: 1 }
36553
+ ] }], void 0, void 0, resources, activeFonts, depth);
36554
+ stateStack.pop();
36555
+ };
36535
36556
  const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
36536
36557
  for (const node of nodes) {
36537
36558
  switch (node.kind) {
@@ -36715,7 +36736,8 @@ function evaluateContentStreamToDisplayList(params) {
36715
36736
  st.fillAlpha,
36716
36737
  "PatternShading_" + st.fillPatternName,
36717
36738
  patClip,
36718
- shading?.kind === "stream" ? shading : void 0
36739
+ shading?.kind === "stream" ? shading : void 0,
36740
+ st.blendMode
36719
36741
  );
36720
36742
  if (shImg) {
36721
36743
  emit({ kind: "image", value: shImg });
@@ -36824,18 +36846,20 @@ function evaluateContentStreamToDisplayList(params) {
36824
36846
  const subNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "Subtype"));
36825
36847
  const sub = subNode?.kind === "name" ? subNode.decoded : "";
36826
36848
  if (sub === "Image") {
36849
+ const maskNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "ImageMask"));
36850
+ const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
36827
36851
  const decoded = decodeXObjectImageToRgba(
36828
36852
  params.cosDoc,
36829
36853
  xobjNode,
36830
36854
  activeResources,
36831
- {
36855
+ patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
36832
36856
  r: st.fillColor.r,
36833
36857
  g: st.fillColor.g,
36834
36858
  b: st.fillColor.b,
36835
36859
  alpha: st.fillAlpha
36836
36860
  }
36837
36861
  );
36838
- emit({ kind: "image", value: {
36862
+ paintImage({
36839
36863
  name: node.name,
36840
36864
  matrix: [...st.ctm],
36841
36865
  width: decoded.width,
@@ -36845,7 +36869,7 @@ function evaluateContentStreamToDisplayList(params) {
36845
36869
  decodedRgba: decoded.rgba,
36846
36870
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
36847
36871
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
36848
- } });
36872
+ }, patternMask, activeResources, activeFonts, depth);
36849
36873
  } else if (sub === "Form" && depth < 8) {
36850
36874
  const formStreamBytes = params.cosDoc.decodeStream(xobjNode);
36851
36875
  const formNodes = parseContentStream(formStreamBytes);
@@ -36901,19 +36925,22 @@ function evaluateContentStreamToDisplayList(params) {
36901
36925
  }
36902
36926
  case "inline-image": {
36903
36927
  const st = curState();
36928
+ const maskEntry = dictGet(node.dict, "ImageMask") ?? dictGet(node.dict, "IM");
36929
+ const maskNode = params.cosDoc ? params.cosDoc.resolve(maskEntry) : maskEntry;
36930
+ const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
36904
36931
  const decoded = decodeInlineImageNodeToRgba(
36905
36932
  params.cosDoc,
36906
36933
  node.dict,
36907
36934
  node.data,
36908
36935
  activeResources,
36909
- {
36936
+ patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
36910
36937
  r: st.fillColor.r,
36911
36938
  g: st.fillColor.g,
36912
36939
  b: st.fillColor.b,
36913
36940
  alpha: st.fillAlpha
36914
36941
  }
36915
36942
  );
36916
- emit({ kind: "image", value: {
36943
+ paintImage({
36917
36944
  name: "InlineImage",
36918
36945
  matrix: [...st.ctm],
36919
36946
  width: decoded.width,
@@ -36923,7 +36950,7 @@ function evaluateContentStreamToDisplayList(params) {
36923
36950
  decodedRgba: decoded.rgba,
36924
36951
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
36925
36952
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
36926
- } });
36953
+ }, patternMask, activeResources, activeFonts, depth);
36927
36954
  break;
36928
36955
  }
36929
36956
  case "text-object": {
@@ -41360,6 +41387,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
41360
41387
  const aaVec = options.antialiasVector !== false;
41361
41388
  const aaTxt = options.antialiasText !== false;
41362
41389
  const clipMasks = /* @__PURE__ */ new Map();
41390
+ const imageClipMasks = /* @__PURE__ */ new Map();
41363
41391
  for (const original of paintOperations(displayList)) {
41364
41392
  if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
41365
41393
  const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
@@ -41374,6 +41402,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
41374
41402
  }
41375
41403
  clipMasks.set(clips, clipMask);
41376
41404
  }
41405
+ const imageClips = original.value.clipImages;
41406
+ if (imageClips) {
41407
+ let imageMask = imageClipMasks.get(imageClips);
41408
+ if (!imageMask) {
41409
+ imageMask = new Uint8Array(width * height * 4).fill(255);
41410
+ for (const image of imageClips) {
41411
+ const layer = renderDisplayListToBitmap({
41412
+ ...displayList,
41413
+ rotation: 0,
41414
+ paths: [],
41415
+ glyphs: [],
41416
+ images: [image],
41417
+ operations: [{ kind: "image", value: image }]
41418
+ }, { scale, transparent: true }).data;
41419
+ for (let i = 3; i < layer.length; i += 4) imageMask[i] = Math.round(imageMask[i] * layer[i] / 255);
41420
+ }
41421
+ imageClipMasks.set(imageClips, imageMask);
41422
+ }
41423
+ if (clipMask) {
41424
+ clipMask = clipMask.slice();
41425
+ for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * imageMask[i] / 255);
41426
+ } else {
41427
+ clipMask = imageMask;
41428
+ }
41429
+ }
41377
41430
  if (operation.kind === "path") {
41378
41431
  const path = operation.value;
41379
41432
  if (path.fillColor) {
@@ -41522,6 +41575,15 @@ function escapeXmlText(str) {
41522
41575
  }
41523
41576
  return encodeToXmlString(valid);
41524
41577
  }
41578
+ function svgImage(image, pageHeight) {
41579
+ if (!image.decodedRgba) return "";
41580
+ const png = encodeRgbaToPng(image.width, image.height, image.decodedRgba);
41581
+ const chunks = [];
41582
+ for (let offset = 0; offset < png.length; offset += 8192)
41583
+ chunks.push(String.fromCharCode(...png.subarray(offset, offset + 8192)));
41584
+ const [a, b, c, d, e, f] = image.matrix;
41585
+ 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(""))}"/>`;
41586
+ }
41525
41587
  function svgPathData(segments, height) {
41526
41588
  const dParts = [];
41527
41589
  for (const seg of segments) {
@@ -41570,11 +41632,16 @@ function renderDisplayListToSvg(displayList, options = {}) {
41570
41632
  if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
41571
41633
  const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
41572
41634
  const clips = original.value.clipPaths ?? [];
41635
+ const imageClips = original.value.clipImages ?? [];
41573
41636
  for (const segments of clips) {
41574
41637
  const id = `text-clip-${clipId++}`;
41575
41638
  const path = `<path d="${svgPathData(segments, displayList.height)}"/>`;
41576
41639
  parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
41577
41640
  }
41641
+ for (const image of imageClips) {
41642
+ const id = `image-clip-${clipId++}`;
41643
+ 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})">`);
41644
+ }
41578
41645
  if (operation.kind === "path") {
41579
41646
  const p = operation.value;
41580
41647
  const pathData = svgPathData(p.segments, displayList.height);
@@ -41594,24 +41661,9 @@ function renderDisplayListToSvg(displayList, options = {}) {
41594
41661
  parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
41595
41662
  }
41596
41663
  } else if (operation.kind === "image") {
41597
- const img = operation.value;
41598
- if (!img.decodedRgba) {
41599
- for (let i = 0; i < clips.length; i++) parts.push("</g>");
41600
- continue;
41601
- }
41602
- const pngBytes = encodeRgbaToPng(img.width, img.height, img.decodedRgba);
41603
- const chunks = [];
41604
- for (let offset = 0; offset < pngBytes.length; offset += 8192)
41605
- chunks.push(String.fromCharCode(...pngBytes.subarray(offset, offset + 8192)));
41606
- const b64 = btoa(chunks.join(""));
41607
- const [a, b, c, d, e, f] = img.matrix;
41608
- const svgTx = e + c;
41609
- const svgTy = displayList.height - f - d;
41610
- parts.push(
41611
- ` <image width="1" height="1" preserveAspectRatio="none" transform="matrix(${a} ${-b} ${-c} ${d} ${svgTx} ${svgTy})" href="data:image/png;base64,${b64}"/>`
41612
- );
41664
+ parts.push(` ${svgImage(operation.value, displayList.height)}`);
41613
41665
  }
41614
- for (let i = 0; i < clips.length; i++) parts.push("</g>");
41666
+ for (let i = 0; i < clips.length + imageClips.length; i++) parts.push("</g>");
41615
41667
  }
41616
41668
  if (displayList.rotation) parts.push("</g>");
41617
41669
  parts.push("</svg>\n");
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  digit,
3
3
  letter
4
- } from "./chunk-VTWKS4RM.js";
4
+ } from "./chunk-WF2LSKMI.js";
5
5
  import {
6
6
  unicodeWhitespace
7
7
  } from "./chunk-UI6H6YG4.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pipeRow
3
- } from "./chunk-F3J5ZLKF.js";
3
+ } from "./chunk-522TDVLS.js";
4
4
  import {
5
5
  normalizeLabel
6
- } from "./chunk-VTWKS4RM.js";
6
+ } from "./chunk-WF2LSKMI.js";
7
7
  import {
8
8
  init_buffer
9
9
  } from "./chunk-HX3SHTCE.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  bareAutolink,
3
3
  filterGfmHtml
4
- } from "./chunk-F3J5ZLKF.js";
4
+ } from "./chunk-522TDVLS.js";
5
5
  import {
6
6
  asciiPunctuation,
7
7
  decodeSyntax,
@@ -14,7 +14,7 @@ import {
14
14
  readLabel,
15
15
  readTitle,
16
16
  whitespace
17
- } from "./chunk-VTWKS4RM.js";
17
+ } from "./chunk-WF2LSKMI.js";
18
18
  import {
19
19
  unicodePunctuation,
20
20
  unicodeWhitespace
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Interpreter
3
- } from "./chunk-YIK4ZYQ4.js";
3
+ } from "./chunk-DC52GWRK.js";
4
4
  import {
5
5
  parse
6
6
  } from "./chunk-ACRMXIQC.js";
@@ -5141,7 +5141,11 @@ function createResourceIO(options) {
5141
5141
  init_buffer();
5142
5142
 
5143
5143
  export {
5144
+ compareServiceIds,
5144
5145
  createRegistry,
5146
+ FileWriteError,
5147
+ ioFailure,
5148
+ imageFormats,
5145
5149
  defaultSsconvertLimits,
5146
5150
  createEngine,
5147
5151
  createResourceIO
@@ -48,11 +48,11 @@ import {
48
48
  trimImage,
49
49
  unflattenImage,
50
50
  unpremultiplyRgbaImage
51
- } from "./chunk-WI35236J.js";
51
+ } from "./chunk-XYCWDGOG.js";
52
52
  import {
53
53
  PdfDocument,
54
54
  encodePng
55
- } from "./chunk-H2FQA4OU.js";
55
+ } from "./chunk-TCAGGM44.js";
56
56
  import {
57
57
  createLuaFilterCapability
58
58
  } from "./chunk-Y2KHC6TZ.js";
@@ -28747,7 +28747,7 @@ var ParsedCosDocument = class {
28747
28747
  return void 0;
28748
28748
  }
28749
28749
  };
28750
- function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false) {
28750
+ function parseNodeFromLexer(lexer, bytes, maxDepth, repair = false) {
28751
28751
  const stack = [];
28752
28752
  while (true) {
28753
28753
  const tok = lexer.nextToken();
@@ -28756,7 +28756,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
28756
28756
  if (!parent) return void 0;
28757
28757
  throw new PdfError("E_PARSE", parent.kind === "array" ? "Unterminated PDF array" : "Unterminated PDF dictionary");
28758
28758
  }
28759
- if (!parent && recoverEmptyObject && tok.kind === "keyword" && tok.value === "endobj") {
28759
+ if (!parent && repair && tok.kind === "keyword" && tok.value === "endobj") {
28760
28760
  return { kind: "null", span: tok.span };
28761
28761
  }
28762
28762
  let node;
@@ -28771,6 +28771,7 @@ function parseNodeFromLexer(lexer, bytes, maxDepth, recoverEmptyObject = false)
28771
28771
  parent.key = { kind: "name", rawBytes: tok.rawBytes, decoded: tok.decoded, span: tok.span };
28772
28772
  continue;
28773
28773
  } else {
28774
+ if (repair) continue;
28774
28775
  throw new PdfError("E_PARSE", `Expected dictionary key /Name, got ${tok.kind}`);
28775
28776
  }
28776
28777
  } else {
@@ -28939,7 +28940,7 @@ function parseHeaderVersion(bytes) {
28939
28940
  }
28940
28941
  return head.slice(idx + 5, idx + 8);
28941
28942
  }
28942
- function parseObjectAtOffset(bytes, offset, maxRecursionDepth, recoverEmptyObject = false) {
28943
+ function parseObjectAtOffset(bytes, offset, maxRecursionDepth, repair = false) {
28943
28944
  const lexer = new CosByteLexer(bytes, offset);
28944
28945
  const objNumTok = lexer.nextToken();
28945
28946
  const genNumTok = lexer.nextToken();
@@ -28947,7 +28948,7 @@ function parseObjectAtOffset(bytes, offset, maxRecursionDepth, recoverEmptyObjec
28947
28948
  if (objNumTok?.kind !== "number" || genNumTok?.kind !== "number" || objKwTok?.kind !== "keyword" || objKwTok.value !== "obj") {
28948
28949
  throw new PdfError("E_PARSE", `Malformed indirect object header at byte offset ${offset}`);
28949
28950
  }
28950
- const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, recoverEmptyObject);
28951
+ const value = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, repair);
28951
28952
  if (!value) {
28952
28953
  throw new PdfError("E_PARSE", `Empty indirect object ${objNumTok.value} at offset ${offset}`);
28953
28954
  }
@@ -29136,7 +29137,7 @@ function repairScanCosDocument(bytes, maxObjects, maxRecursionDepth) {
29136
29137
  try {
29137
29138
  const token = lexer.nextToken();
29138
29139
  if (token?.kind === "keyword" && token.value === "trailer") {
29139
- const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth);
29140
+ const trailer = parseNodeFromLexer(lexer, bytes, maxRecursionDepth, true);
29140
29141
  if (trailer?.kind === "dict") trailers.push(trailer);
29141
29142
  pos = lexer.offset;
29142
29143
  continue;
@@ -29192,7 +29193,7 @@ function unpackRecoveredObjects(objects, maxObjects, maxDecompressedBytes, maxRe
29192
29193
  const t = dictGet(obj.value.dict, "Type");
29193
29194
  if (t?.kind === "name" && t.decoded === "ObjStm") {
29194
29195
  try {
29195
- for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth).entries()) {
29196
+ for (const [unpackedNum, unpackedVal] of unpackObjectStream(obj.value, maxDecompressedBytes, maxRecursionDepth, true).entries()) {
29196
29197
  if (!objects.has(unpackedNum)) {
29197
29198
  objects.set(unpackedNum, {
29198
29199
  objectNumber: unpackedNum,
@@ -29228,7 +29229,7 @@ function recoveredReferences(objects) {
29228
29229
  }
29229
29230
  return { ...rootRef ? { rootRef } : {}, ...infoRef ? { infoRef } : {} };
29230
29231
  }
29231
- function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth) {
29232
+ function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth, repair = false) {
29232
29233
  const nNode = dictGet(streamObj.dict, "N");
29233
29234
  const firstNode = dictGet(streamObj.dict, "First");
29234
29235
  if (nNode?.kind !== "number" || firstNode?.kind !== "number") {
@@ -29248,7 +29249,7 @@ function unpackObjectStream(streamObj, maxDecompressedBytes, maxRecursionDepth)
29248
29249
  for (const pair of pairs) {
29249
29250
  try {
29250
29251
  const valLexer = new CosByteLexer(decoded, firstNode.value + pair.relativeOffset);
29251
- const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth);
29252
+ const node = parseNodeFromLexer(valLexer, decoded, maxRecursionDepth, repair);
29252
29253
  if (node) {
29253
29254
  result.set(pair.objectNumber, node);
29254
29255
  }
@@ -29431,7 +29432,7 @@ function parseCosDocument(bytes, options = {}) {
29431
29432
  if (!unpacked) {
29432
29433
  const stmObj = objects.get(entry.objectStreamNumber)?.value;
29433
29434
  if (stmObj?.kind === "stream") {
29434
- unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth);
29435
+ unpacked = unpackObjectStream(stmObj, maxDecompressedBytes, maxRecursionDepth, recovery === "repair");
29435
29436
  objStmCache.set(entry.objectStreamNumber, unpacked);
29436
29437
  }
29437
29438
  }
@@ -30939,7 +30940,11 @@ function resolvePageFonts(doc, resourcesDict) {
30939
30940
  let cmap;
30940
30941
  const toUniNode = doc.resolve(dictGet(fObj, "ToUnicode"));
30941
30942
  if (toUniNode?.kind === "stream") {
30942
- cmap = parseToUnicodeCMap(doc.decodeStream(toUniNode));
30943
+ try {
30944
+ cmap = parseToUnicodeCMap(doc.decodeStream(toUniNode));
30945
+ } catch (error) {
30946
+ if (error instanceof PdfError && error.code === "E_LIMIT") throw error;
30947
+ }
30943
30948
  }
30944
30949
  const encNode = doc.resolve(dictGet(fObj, "Encoding"));
30945
30950
  if (encNode?.kind === "dict") {
@@ -32063,8 +32068,12 @@ function evaluateContentStreamToDisplayList(params) {
32063
32068
  const images = [];
32064
32069
  const operations = [];
32065
32070
  const emit = (operation) => {
32066
- const clipPaths = curState().clipPaths;
32067
- if (clipPaths) operation = { ...operation, value: { ...operation.value, clipPaths } };
32071
+ const { clipPaths, clipImages } = curState();
32072
+ if (clipPaths || clipImages) operation = { ...operation, value: {
32073
+ ...operation.value,
32074
+ ...clipPaths ? { clipPaths } : {},
32075
+ ...clipImages ? { clipImages } : {}
32076
+ } };
32068
32077
  operations.push(operation);
32069
32078
  switch (operation.kind) {
32070
32079
  case "path":
@@ -32328,6 +32337,18 @@ function evaluateContentStreamToDisplayList(params) {
32328
32337
  let hasTextClip = false;
32329
32338
  let activeTm = [1, 0, 0, 1, 0, 0];
32330
32339
  let activeTlm = [1, 0, 0, 1, 0, 0];
32340
+ const paintImage = (image, patternMask, resources, activeFonts, depth) => {
32341
+ if (!patternMask) {
32342
+ emit({ kind: "image", value: image });
32343
+ return;
32344
+ }
32345
+ const st = curState();
32346
+ stateStack.push({ ...st, clipImages: [...st.clipImages ?? [], image] });
32347
+ walkNodes([{ kind: "path-op", paint: "f", segments: [
32348
+ { kind: "rect", x: 0, y: 0, width: 1, height: 1 }
32349
+ ] }], void 0, void 0, resources, activeFonts, depth);
32350
+ stateStack.pop();
32351
+ };
32331
32352
  const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
32332
32353
  for (const node of nodes) {
32333
32354
  switch (node.kind) {
@@ -32511,7 +32532,8 @@ function evaluateContentStreamToDisplayList(params) {
32511
32532
  st.fillAlpha,
32512
32533
  "PatternShading_" + st.fillPatternName,
32513
32534
  patClip,
32514
- shading?.kind === "stream" ? shading : void 0
32535
+ shading?.kind === "stream" ? shading : void 0,
32536
+ st.blendMode
32515
32537
  );
32516
32538
  if (shImg) {
32517
32539
  emit({ kind: "image", value: shImg });
@@ -32620,18 +32642,20 @@ function evaluateContentStreamToDisplayList(params) {
32620
32642
  const subNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "Subtype"));
32621
32643
  const sub = subNode?.kind === "name" ? subNode.decoded : "";
32622
32644
  if (sub === "Image") {
32645
+ const maskNode = params.cosDoc.resolve(dictGet(xobjNode.dict, "ImageMask"));
32646
+ const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
32623
32647
  const decoded = decodeXObjectImageToRgba(
32624
32648
  params.cosDoc,
32625
32649
  xobjNode,
32626
32650
  activeResources,
32627
- {
32651
+ patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
32628
32652
  r: st.fillColor.r,
32629
32653
  g: st.fillColor.g,
32630
32654
  b: st.fillColor.b,
32631
32655
  alpha: st.fillAlpha
32632
32656
  }
32633
32657
  );
32634
- emit({ kind: "image", value: {
32658
+ paintImage({
32635
32659
  name: node.name,
32636
32660
  matrix: [...st.ctm],
32637
32661
  width: decoded.width,
@@ -32641,7 +32665,7 @@ function evaluateContentStreamToDisplayList(params) {
32641
32665
  decodedRgba: decoded.rgba,
32642
32666
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
32643
32667
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
32644
- } });
32668
+ }, patternMask, activeResources, activeFonts, depth);
32645
32669
  } else if (sub === "Form" && depth < 8) {
32646
32670
  const formStreamBytes = params.cosDoc.decodeStream(xobjNode);
32647
32671
  const formNodes = parseContentStream(formStreamBytes);
@@ -32697,19 +32721,22 @@ function evaluateContentStreamToDisplayList(params) {
32697
32721
  }
32698
32722
  case "inline-image": {
32699
32723
  const st = curState();
32724
+ const maskEntry = dictGet(node.dict, "ImageMask") ?? dictGet(node.dict, "IM");
32725
+ const maskNode = params.cosDoc ? params.cosDoc.resolve(maskEntry) : maskEntry;
32726
+ const patternMask = !!st.fillPatternName && maskNode?.kind === "boolean" && maskNode.value;
32700
32727
  const decoded = decodeInlineImageNodeToRgba(
32701
32728
  params.cosDoc,
32702
32729
  node.dict,
32703
32730
  node.data,
32704
32731
  activeResources,
32705
- {
32732
+ patternMask ? { r: 1, g: 1, b: 1, alpha: 1 } : {
32706
32733
  r: st.fillColor.r,
32707
32734
  g: st.fillColor.g,
32708
32735
  b: st.fillColor.b,
32709
32736
  alpha: st.fillAlpha
32710
32737
  }
32711
32738
  );
32712
- emit({ kind: "image", value: {
32739
+ paintImage({
32713
32740
  name: "InlineImage",
32714
32741
  matrix: [...st.ctm],
32715
32742
  width: decoded.width,
@@ -32719,7 +32746,7 @@ function evaluateContentStreamToDisplayList(params) {
32719
32746
  decodedRgba: decoded.rgba,
32720
32747
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
32721
32748
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
32722
- } });
32749
+ }, patternMask, activeResources, activeFonts, depth);
32723
32750
  break;
32724
32751
  }
32725
32752
  case "text-object": {
@@ -34854,6 +34881,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
34854
34881
  const aaVec = options.antialiasVector !== false;
34855
34882
  const aaTxt = options.antialiasText !== false;
34856
34883
  const clipMasks = /* @__PURE__ */ new Map();
34884
+ const imageClipMasks = /* @__PURE__ */ new Map();
34857
34885
  for (const original of paintOperations(displayList)) {
34858
34886
  if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
34859
34887
  const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
@@ -34868,6 +34896,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
34868
34896
  }
34869
34897
  clipMasks.set(clips, clipMask);
34870
34898
  }
34899
+ const imageClips = original.value.clipImages;
34900
+ if (imageClips) {
34901
+ let imageMask = imageClipMasks.get(imageClips);
34902
+ if (!imageMask) {
34903
+ imageMask = new Uint8Array(width * height * 4).fill(255);
34904
+ for (const image of imageClips) {
34905
+ const layer = renderDisplayListToBitmap({
34906
+ ...displayList,
34907
+ rotation: 0,
34908
+ paths: [],
34909
+ glyphs: [],
34910
+ images: [image],
34911
+ operations: [{ kind: "image", value: image }]
34912
+ }, { scale, transparent: true }).data;
34913
+ for (let i = 3; i < layer.length; i += 4) imageMask[i] = Math.round(imageMask[i] * layer[i] / 255);
34914
+ }
34915
+ imageClipMasks.set(imageClips, imageMask);
34916
+ }
34917
+ if (clipMask) {
34918
+ clipMask = clipMask.slice();
34919
+ for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * imageMask[i] / 255);
34920
+ } else {
34921
+ clipMask = imageMask;
34922
+ }
34923
+ }
34871
34924
  if (operation.kind === "path") {
34872
34925
  const path = operation.value;
34873
34926
  if (path.fillColor) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PdfDocument,
3
3
  renderPdfPageToPng
4
- } from "./chunk-H2FQA4OU.js";
4
+ } from "./chunk-TCAGGM44.js";
5
5
  import {
6
6
  init_buffer
7
7
  } from "./chunk-HX3SHTCE.js";