@poe-platform/safe-bash 0.1.761 → 0.1.763

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 (32) hide show
  1. package/dist/image-ast/index.browser.js +255 -62
  2. package/dist/image-ast/index.js +255 -62
  3. package/dist/pdf-ast/ast.d.ts +23 -0
  4. package/dist/pdf-ast/index.js +344 -98
  5. package/dist/safe-bash/command-chunks/{chunk-6VX5ZQL5.js → chunk-4XHONGIU.js} +2 -2
  6. package/dist/safe-bash/command-chunks/{chunk-OSMLVM7P.js → chunk-S3G2B4OX.js} +258 -62
  7. package/dist/safe-bash/command-chunks/{chunk-GR725WRX.js → chunk-S5EX6UP5.js} +1 -1
  8. package/dist/safe-bash/commands/csvcut/index.d.ts +1 -1
  9. package/dist/safe-bash/commands/csvcut/index.js +3 -1
  10. package/dist/safe-bash/commands/csvgrep/index.d.ts +1 -1
  11. package/dist/safe-bash/commands/csvgrep/index.js +3 -1
  12. package/dist/safe-bash/core.browser.js +8 -6
  13. package/dist/safe-bash/shell/runtime.js +5 -5
  14. package/dist/safe-bash-checksum-engine/index.d.ts +1 -1
  15. package/dist/safe-bash-checksum-engine/index.js +5 -1
  16. package/dist/safe-bash-command-ffmpeg/index.js +7942 -7853
  17. package/dist/safe-bash-command-gh/index.js +174 -105
  18. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  19. package/dist/safe-bash-command-pandoc/command.js +3 -3
  20. package/dist/safe-bash-command-pandoc/index.js +3 -3
  21. package/dist/safe-bash-command-pdfimages/index.js +255 -62
  22. package/dist/safe-bash-command-pdfinfo/index.js +342 -98
  23. package/dist/safe-bash-command-pdftk/index.js +255 -62
  24. package/dist/safe-bash-command-pdftoppm/index.js +342 -98
  25. package/dist/safe-bash-command-pdftotext/index.js +255 -62
  26. package/dist/safe-bash-command-qpdf/index.js +255 -62
  27. package/dist/safe-bash-command-sips/index.js +2 -2
  28. package/dist/safe-bash-command-soffice/index.js +1 -1
  29. package/dist/safe-bash-command-ssconvert/index.js +318 -65
  30. package/dist/safe-bash-command-wkhtmltopdf/index.js +255 -62
  31. package/package.json +2 -2
  32. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +23 -0
@@ -35568,14 +35568,18 @@ function evaluateContentStreamToDisplayList(params) {
35568
35568
  const paths = [];
35569
35569
  const images = [];
35570
35570
  const operations = [];
35571
+ let capturedOperations;
35572
+ let insideSoftMask = false;
35571
35573
  const emit = (operation) => {
35572
- const { clipPaths, clipImages } = curState();
35573
- if (clipPaths || clipImages) operation = { ...operation, value: {
35574
+ const { clipPaths, clipImages, softMask } = curState();
35575
+ if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
35574
35576
  ...operation.value,
35575
35577
  ...clipPaths ? { clipPaths } : {},
35576
- ...clipImages ? { clipImages } : {}
35578
+ ...clipImages ? { clipImages } : {},
35579
+ ...softMask ? { softMask } : {}
35577
35580
  } };
35578
- operations.push(operation);
35581
+ (capturedOperations ?? operations).push(operation);
35582
+ if (insideSoftMask) return;
35579
35583
  switch (operation.kind) {
35580
35584
  case "path":
35581
35585
  paths.push(operation.value);
@@ -35681,7 +35685,7 @@ function evaluateContentStreamToDisplayList(params) {
35681
35685
  );
35682
35686
  return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
35683
35687
  };
35684
- const applyStateOperator = (st, operator, ops, activeResources) => {
35688
+ const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
35685
35689
  const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
35686
35690
  if (operator === "cm") {
35687
35691
  const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
@@ -35764,6 +35768,46 @@ function evaluateContentStreamToDisplayList(params) {
35764
35768
  const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
35765
35769
  const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
35766
35770
  if (gsDict) {
35771
+ const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
35772
+ if (mask?.kind === "name" && mask.decoded === "None") {
35773
+ st.softMask = void 0;
35774
+ } else if (mask?.kind === "dict") {
35775
+ const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
35776
+ const form = params.cosDoc.resolve(dictGet(mask, "G"));
35777
+ if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
35778
+ if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
35779
+ const parentOperations = capturedOperations;
35780
+ const parentInsideSoftMask = insideSoftMask;
35781
+ const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
35782
+ const captured = [];
35783
+ capturedOperations = captured;
35784
+ insideSoftMask = true;
35785
+ const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
35786
+ delete maskState.clipPaths;
35787
+ delete maskState.clipImages;
35788
+ delete maskState.clipRect;
35789
+ stateStack.push(maskState);
35790
+ try {
35791
+ paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
35792
+ } finally {
35793
+ stateStack.pop();
35794
+ capturedOperations = parentOperations;
35795
+ insideSoftMask = parentInsideSoftMask;
35796
+ ({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
35797
+ }
35798
+ const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
35799
+ const colorSpace = group ? dictGet(group, "CS") : void 0;
35800
+ const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
35801
+ const components = bc?.items.map((item) => {
35802
+ const value = params.cosDoc.resolve(item);
35803
+ return value?.kind === "number" ? value.value : 0;
35804
+ });
35805
+ const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
35806
+ const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
35807
+ const transferMap = transfer?.kind === "dict" || transfer?.kind === "stream" ? Uint8Array.from({ length: 256 }, (_, i) => Math.floor(kClamp(Math.fround(evalShadingFunctionToComponents(params.cosDoc, transfer, Math.fround(i / 255))[0] ?? 0)) * 255)) : void 0;
35808
+ st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
35809
+ }
35810
+ }
35767
35811
  const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
35768
35812
  if (bmNode?.kind === "name") {
35769
35813
  st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
@@ -35850,6 +35894,84 @@ function evaluateContentStreamToDisplayList(params) {
35850
35894
  ] }], void 0, void 0, resources, activeFonts, depth);
35851
35895
  stateStack.pop();
35852
35896
  };
35897
+ const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
35898
+ const st = curState();
35899
+ const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
35900
+ const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
35901
+ const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
35902
+ const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
35903
+ const formStreamBytes = params.cosDoc.decodeStream(form);
35904
+ const formNodes = parseContentStream(formStreamBytes);
35905
+ const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
35906
+ const formFonts = new Map(activeFonts);
35907
+ for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
35908
+ formFonts.set(k, v);
35909
+ }
35910
+ let nextCtm = [...st.ctm];
35911
+ const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
35912
+ if (matArr && matArr.items.length >= 6) {
35913
+ const mn = (idx, fb = 0) => {
35914
+ const resolved = params.cosDoc.resolve(matArr.items[idx]);
35915
+ return resolved?.kind === "number" ? resolved.value : fb;
35916
+ };
35917
+ const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
35918
+ nextCtm = multiplyMatrices(formMat, nextCtm);
35919
+ }
35920
+ let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
35921
+ let nextClipPaths = isolate ? void 0 : st.clipPaths;
35922
+ const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
35923
+ if (bboxArr && bboxArr.items.length >= 4) {
35924
+ const bn = (idx, fb = 0) => {
35925
+ const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
35926
+ return resolved?.kind === "number" ? resolved.value : fb;
35927
+ };
35928
+ const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
35929
+ const pts = [
35930
+ transformPoint(nextCtm, bx0, by0),
35931
+ transformPoint(nextCtm, bx1, by0),
35932
+ transformPoint(nextCtm, bx1, by1),
35933
+ transformPoint(nextCtm, bx0, by1)
35934
+ ];
35935
+ nextClipPaths = [...nextClipPaths ?? [], [
35936
+ ...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
35937
+ { kind: "close" }
35938
+ ]];
35939
+ const fMinX = Math.min(...pts.map((p) => p[0]));
35940
+ const fMinY = Math.min(...pts.map((p) => p[1]));
35941
+ const fMaxX = Math.max(...pts.map((p) => p[0]));
35942
+ const fMaxY = Math.max(...pts.map((p) => p[1]));
35943
+ if (fMaxX > fMinX && fMaxY > fMinY) {
35944
+ nextClip = nextClip ? [
35945
+ Math.max(nextClip[0], fMinX),
35946
+ Math.max(nextClip[1], fMinY),
35947
+ Math.min(nextClip[2], fMaxX),
35948
+ Math.min(nextClip[3], fMaxY)
35949
+ ] : [fMinX, fMinY, fMaxX, fMaxY];
35950
+ }
35951
+ }
35952
+ const parentOperations = capturedOperations;
35953
+ const children = [];
35954
+ const nextState = { ...st, ctm: nextCtm };
35955
+ if (isolate) {
35956
+ capturedOperations = children;
35957
+ nextState.fillAlpha = nextState.strokeAlpha = 1;
35958
+ nextState.blendMode = "Normal";
35959
+ nextState.softMask = void 0;
35960
+ delete nextState.clipImages;
35961
+ delete nextState.clipPaths;
35962
+ delete nextState.clipRect;
35963
+ }
35964
+ if (nextClip) nextState.clipRect = nextClip;
35965
+ if (nextClipPaths) nextState.clipPaths = nextClipPaths;
35966
+ stateStack.push(nextState);
35967
+ try {
35968
+ walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
35969
+ } finally {
35970
+ stateStack.pop();
35971
+ capturedOperations = parentOperations;
35972
+ }
35973
+ if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
35974
+ };
35853
35975
  const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
35854
35976
  for (const node of nodes) {
35855
35977
  switch (node.kind) {
@@ -35894,7 +36016,7 @@ function evaluateContentStreamToDisplayList(params) {
35894
36016
  break;
35895
36017
  }
35896
36018
  case "state-op": {
35897
- applyStateOperator(curState(), node.operator, node.operands, activeResources);
36019
+ applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
35898
36020
  break;
35899
36021
  }
35900
36022
  case "path-op": {
@@ -36180,53 +36302,7 @@ function evaluateContentStreamToDisplayList(params) {
36180
36302
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
36181
36303
  }, patternMask, activeResources, activeFonts, depth);
36182
36304
  } else if (sub === "Form" && depth < 8) {
36183
- const formStreamBytes = params.cosDoc.decodeStream(xobjNode);
36184
- const formNodes = parseContentStream(formStreamBytes);
36185
- const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
36186
- const formFonts = new Map(activeFonts);
36187
- for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
36188
- formFonts.set(k, v);
36189
- }
36190
- let nextCtm = [...st.ctm];
36191
- const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
36192
- if (matArr && matArr.items.length >= 6) {
36193
- const mn = (idx, fb = 0) => {
36194
- const resolved = params.cosDoc.resolve(matArr.items[idx]);
36195
- return resolved?.kind === "number" ? resolved.value : fb;
36196
- };
36197
- const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
36198
- nextCtm = multiplyMatrices(formMat, nextCtm);
36199
- }
36200
- let nextClip = st.clipRect ? [...st.clipRect] : void 0;
36201
- const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
36202
- if (bboxArr && bboxArr.items.length >= 4) {
36203
- const bn = (idx, fb = 0) => {
36204
- const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
36205
- return resolved?.kind === "number" ? resolved.value : fb;
36206
- };
36207
- const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
36208
- const pts = [
36209
- transformPoint(nextCtm, bx0, by0),
36210
- transformPoint(nextCtm, bx1, by0),
36211
- transformPoint(nextCtm, bx0, by1),
36212
- transformPoint(nextCtm, bx1, by1)
36213
- ];
36214
- const fMinX = Math.min(...pts.map((p) => p[0]));
36215
- const fMinY = Math.min(...pts.map((p) => p[1]));
36216
- const fMaxX = Math.max(...pts.map((p) => p[0]));
36217
- const fMaxY = Math.max(...pts.map((p) => p[1]));
36218
- if (fMaxX > fMinX && fMaxY > fMinY) {
36219
- nextClip = nextClip ? [
36220
- Math.max(nextClip[0], fMinX),
36221
- Math.max(nextClip[1], fMinY),
36222
- Math.min(nextClip[2], fMaxX),
36223
- Math.min(nextClip[3], fMaxY)
36224
- ] : [fMinX, fMinY, fMaxX, fMaxY];
36225
- }
36226
- }
36227
- stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
36228
- walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
36229
- if (stateStack.length > 1) stateStack.pop();
36305
+ paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
36230
36306
  }
36231
36307
  }
36232
36308
  }
@@ -36445,7 +36521,7 @@ function evaluateContentStreamToDisplayList(params) {
36445
36521
  st.textRenderMode = cmd.mode;
36446
36522
  break;
36447
36523
  case "state-op":
36448
- applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
36524
+ applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
36449
36525
  break;
36450
36526
  case "show-text":
36451
36527
  emitTokenBytes(cmd.token.bytes);
@@ -38818,6 +38894,47 @@ function flattenCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
38818
38894
  points.push([x4, y4]);
38819
38895
  return points;
38820
38896
  }
38897
+ function sampleImageLinear(image, x, y, out) {
38898
+ x = Math.max(0, Math.min(image.width - 1, x));
38899
+ y = Math.max(0, Math.min(image.height - 1, y));
38900
+ const x0 = Math.floor(x), y0 = Math.floor(y);
38901
+ const fx = x - x0, fy = y - y0;
38902
+ out.fill(0);
38903
+ for (let j = 0; j < 2; j++) {
38904
+ for (let i = 0; i < 2; i++) {
38905
+ const offset = (Math.min(image.height - 1, y0 + j) * image.width + Math.min(image.width - 1, x0 + i)) * 4;
38906
+ const alpha = image.data[offset + 3] * (i ? fx : 1 - fx) * (j ? fy : 1 - fy);
38907
+ out[0] = out[0] + image.data[offset] * alpha;
38908
+ out[1] = out[1] + image.data[offset + 1] * alpha;
38909
+ out[2] = out[2] + image.data[offset + 2] * alpha;
38910
+ out[3] = out[3] + alpha;
38911
+ }
38912
+ }
38913
+ if (out[3] > 0) {
38914
+ out[0] = out[0] / out[3];
38915
+ out[1] = out[1] / out[3];
38916
+ out[2] = out[2] / out[3];
38917
+ }
38918
+ }
38919
+ function downscaleImage(image, widthScale, heightScale) {
38920
+ const sample = new Float64Array(4);
38921
+ while (widthScale > 2 && image.width > 1 || heightScale > 2 && image.height > 1) {
38922
+ const width = widthScale > 2 ? Math.ceil(image.width / 2) : image.width;
38923
+ const height = heightScale > 2 ? Math.ceil(image.height / 2) : image.height;
38924
+ const data = new Uint8Array(width * height * 4);
38925
+ for (let y = 0; y < height; y++) {
38926
+ for (let x = 0; x < width; x++) {
38927
+ sampleImageLinear(image, (x + 0.5) * image.width / width - 0.5, (y + 0.5) * image.height / height - 0.5, sample);
38928
+ const offset = (y * width + x) * 4;
38929
+ for (let c = 0; c < 4; c++) data[offset + c] = Math.round(sample[c]);
38930
+ }
38931
+ }
38932
+ widthScale /= image.width / width;
38933
+ heightScale /= image.height / height;
38934
+ image = { width, height, data };
38935
+ }
38936
+ return image;
38937
+ }
38821
38938
  function decodePng(pngBytes) {
38822
38939
  if (pngBytes.length < 24 || pngBytes[0] !== 137 || pngBytes[1] !== 80 || pngBytes[2] !== 78 || pngBytes[3] !== 71) {
38823
38940
  throw new Error("Invalid PNG signature");
@@ -39727,6 +39844,30 @@ function paintOperations(displayList) {
39727
39844
  ...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
39728
39845
  ];
39729
39846
  }
39847
+ function renderSoftMask(mask, displayList, scale) {
39848
+ const bitmap = renderDisplayListToBitmap({
39849
+ ...displayList,
39850
+ rotation: 0,
39851
+ glyphs: [],
39852
+ paths: [],
39853
+ images: [],
39854
+ operations: mask.operations
39855
+ }, { scale, transparent: true });
39856
+ const { data } = bitmap;
39857
+ for (let i = 0; i < data.length; i += 4) {
39858
+ let value = data[i + 3];
39859
+ if (mask.subtype === "Luminosity") {
39860
+ const alpha = value / 255;
39861
+ const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
39862
+ const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
39863
+ const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
39864
+ value = Math.round(pdfLum(r, g, b));
39865
+ }
39866
+ data[i] = data[i + 1] = data[i + 2] = 0;
39867
+ data[i + 3] = mask.transferMap?.[value] ?? value;
39868
+ }
39869
+ return bitmap;
39870
+ }
39730
39871
  function renderDisplayListToBitmap(displayList, options = {}) {
39731
39872
  const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
39732
39873
  const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
@@ -39750,10 +39891,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
39750
39891
  const aaTxt = options.antialiasText !== false;
39751
39892
  let cachedClips;
39752
39893
  let cachedClipMask;
39894
+ let cachedSoftMask;
39895
+ let cachedSoftMaskPixels;
39753
39896
  const imageClipMasks = /* @__PURE__ */ new Map();
39754
39897
  for (const original of paintOperations(displayList)) {
39755
39898
  if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
39756
- const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
39899
+ let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
39900
+ if (operation.kind === "group") {
39901
+ const group = operation.value;
39902
+ const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
39903
+ for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
39904
+ operation = { kind: "image", value: {
39905
+ name: "TransparencyGroup",
39906
+ width: bitmap.width,
39907
+ height: bitmap.height,
39908
+ decodedRgba: bitmap.data,
39909
+ matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
39910
+ colorSpace: "DeviceRGB",
39911
+ bitsPerComponent: 8,
39912
+ blendMode: group.blendMode,
39913
+ clipRect: group.clipRect
39914
+ } };
39915
+ }
39757
39916
  const clips = original.value.clipPaths;
39758
39917
  let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
39759
39918
  if (clips && !clipMask) {
@@ -39767,6 +39926,19 @@ function renderDisplayListToBitmap(displayList, options = {}) {
39767
39926
  cachedClips = clips;
39768
39927
  cachedClipMask = clipMask;
39769
39928
  }
39929
+ const softMask = original.value.softMask;
39930
+ if (softMask) {
39931
+ if (softMask !== cachedSoftMask) {
39932
+ cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
39933
+ cachedSoftMask = softMask;
39934
+ }
39935
+ if (clipMask) {
39936
+ clipMask = clipMask.slice();
39937
+ for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
39938
+ } else {
39939
+ clipMask = cachedSoftMaskPixels;
39940
+ }
39941
+ }
39770
39942
  const imageClips = original.value.clipImages;
39771
39943
  if (imageClips) {
39772
39944
  let imageMask = imageClipMasks.get(imageClips);
@@ -39870,6 +40042,17 @@ function renderDisplayListToBitmap(displayList, options = {}) {
39870
40042
  const maxPx = Math.min(width - 1, clipMaxPx, Math.ceil(Math.max(...cornersPx)) - 1);
39871
40043
  const minPy = Math.max(0, clipMinPy, Math.floor(Math.min(...cornersPy)));
39872
40044
  const maxPy = Math.min(height - 1, clipMaxPy, Math.ceil(Math.max(...cornersPy)) - 1);
40045
+ if (minPx > maxPx || minPy > maxPy) continue;
40046
+ const source = downscaleImage(
40047
+ { width: img.width, height: img.height, data: img.decodedRgba },
40048
+ Math.hypot(d, c) * img.width / Math.abs(det * scale),
40049
+ Math.hypot(b, a) * img.height / Math.abs(det * scale)
40050
+ );
40051
+ const ax = a * scale / img.width, ay = b * scale / img.width;
40052
+ const bx = c * scale / img.height, by = d * scale / img.height;
40053
+ const s1 = ax * ax + ay * ay, s2 = bx * bx + by * by, cross = ax * bx + ay * by;
40054
+ const smooth = Math.fround((s1 + s2 + Math.hypot(s1 - s2, 2 * cross)) / 2) <= 1;
40055
+ const sample = new Float64Array(4);
39873
40056
  for (let py = minPy; py <= maxPy; py++) {
39874
40057
  const yPdf = displayList.height - (py + 0.5) / scale;
39875
40058
  if (img.clipRect && (yPdf < img.clipRect[1] || yPdf > img.clipRect[3])) continue;
@@ -39881,9 +40064,14 @@ function renderDisplayListToBitmap(displayList, options = {}) {
39881
40064
  const u = (d * dxPdf - c * dyPdf) / det;
39882
40065
  const v = (-b * dxPdf + a * dyPdf) / det;
39883
40066
  if (u < 0 || u > 1 || v < 0 || v > 1) continue;
39884
- const sx = Math.min(img.width - 1, Math.max(0, Math.floor(u * img.width)));
39885
- const sy = Math.min(img.height - 1, Math.max(0, Math.floor((1 - v) * img.height)));
39886
- const sIdx = (sy * img.width + sx) * 4;
40067
+ if (smooth) {
40068
+ sampleImageLinear(source, u * source.width - 0.5, (1 - v) * source.height - 0.5, sample);
40069
+ } else {
40070
+ const sx = Math.min(source.width - 1, Math.max(0, Math.floor(u * source.width)));
40071
+ const sy = Math.min(source.height - 1, Math.max(0, Math.floor((1 - v) * source.height)));
40072
+ const sIdx = (sy * source.width + sx) * 4;
40073
+ for (let c2 = 0; c2 < 4; c2++) sample[c2] = source.data[sIdx + c2];
40074
+ }
39887
40075
  blendPixel(
39888
40076
  rgba,
39889
40077
  width,
@@ -39891,11 +40079,11 @@ function renderDisplayListToBitmap(displayList, options = {}) {
39891
40079
  px,
39892
40080
  py,
39893
40081
  {
39894
- r: img.decodedRgba[sIdx] / 255,
39895
- g: img.decodedRgba[sIdx + 1] / 255,
39896
- b: img.decodedRgba[sIdx + 2] / 255
40082
+ r: sample[0] / 255,
40083
+ g: sample[1] / 255,
40084
+ b: sample[2] / 255
39897
40085
  },
39898
- img.decodedRgba[sIdx + 3] / 255,
40086
+ sample[3] / 255,
39899
40087
  img.blendMode,
39900
40088
  clipMask
39901
40089
  );
@@ -43124,3 +43312,8 @@ export {
43124
43312
  * Adapted from PDFium third_party/agg23/agg_curves.cpp, curve4_div.
43125
43313
  * See THIRD_PARTY_NOTICES.md for the pinned revision and adaptations.
43126
43314
  */
43315
+ /*!
43316
+ * Staged image reduction adapted from Mozilla PDF.js CanvasGraphics._scaleImage.
43317
+ * Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
43318
+ * See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
43319
+ */
@@ -11,8 +11,8 @@ import {
11
11
  readImageMetadata,
12
12
  resizeImage,
13
13
  rotateImage
14
- } from "../safe-bash/command-chunks/chunk-GR725WRX.js";
15
- import "../safe-bash/command-chunks/chunk-OSMLVM7P.js";
14
+ } from "../safe-bash/command-chunks/chunk-S5EX6UP5.js";
15
+ import "../safe-bash/command-chunks/chunk-S3G2B4OX.js";
16
16
  import {
17
17
  init_buffer
18
18
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -31,7 +31,7 @@ import {
31
31
  PdfDocument,
32
32
  decodeFlate,
33
33
  rgb
34
- } from "../safe-bash/command-chunks/chunk-OSMLVM7P.js";
34
+ } from "../safe-bash/command-chunks/chunk-S3G2B4OX.js";
35
35
  import {
36
36
  init_buffer
37
37
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";