@poe-platform/safe-bash 0.1.772 → 0.1.773

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 (39) hide show
  1. package/dist/image-ast/index.browser.js +2801 -556
  2. package/dist/image-ast/index.js +2801 -556
  3. package/dist/pdf-ast/ast.d.ts +7 -0
  4. package/dist/pdf-ast/content/evaluator.d.ts +1 -0
  5. package/dist/pdf-ast/index.js +2845 -568
  6. package/dist/pdf-ast/render/raster.d.ts +1 -0
  7. package/dist/pdf-ast/vendor/pdfjs-fonts.d.mts +24 -0
  8. package/dist/pdf-ast/vendor/pdfjs-fonts.mjs +2621 -0
  9. package/dist/safe-bash/command-chunks/{chunk-M2XU2YCK.js → chunk-5VXZSNM2.js} +2 -2
  10. package/dist/safe-bash/command-chunks/{chunk-C4AAJTXF.js → chunk-B2MM5DIT.js} +2804 -556
  11. package/dist/safe-bash/command-chunks/{chunk-NBENXODJ.js → chunk-G3NVK25P.js} +1 -1
  12. package/dist/safe-bash/core.browser.js +38 -38
  13. package/dist/safe-bash/core.d.ts +1 -1
  14. package/dist/safe-bash/plugins/composition.d.ts +2 -0
  15. package/dist/safe-bash/plugins/composition.js +2 -1
  16. package/dist/safe-bash-command-ffmpeg/index.js +10968 -9719
  17. package/dist/safe-bash-command-gh/index.d.ts +1 -0
  18. package/dist/safe-bash-command-gh/index.js +43 -13
  19. package/dist/safe-bash-command-gh/types.d.ts +1 -0
  20. package/dist/safe-bash-command-git/git_rust.wasm +0 -0
  21. package/dist/safe-bash-command-git/index.js +22 -15
  22. package/dist/safe-bash-command-git/wasm.generated.js +1 -1
  23. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  24. package/dist/safe-bash-command-pandoc/command.js +3 -3
  25. package/dist/safe-bash-command-pandoc/index.js +3 -3
  26. package/dist/safe-bash-command-pdfimages/index.js +2800 -510
  27. package/dist/safe-bash-command-pdfinfo/index.js +2842 -568
  28. package/dist/safe-bash-command-pdftk/index.js +2800 -510
  29. package/dist/safe-bash-command-pdftoppm/index.js +2847 -637
  30. package/dist/safe-bash-command-pdftotext/index.js +2800 -510
  31. package/dist/safe-bash-command-qpdf/index.js +2800 -510
  32. package/dist/safe-bash-command-sips/index.js +2 -2
  33. package/dist/safe-bash-command-soffice/index.js +1 -1
  34. package/dist/safe-bash-command-ssconvert/index.js +2811 -566
  35. package/dist/safe-bash-command-wkhtmltopdf/index.js +2833 -510
  36. package/dist/safe-bash-mcp/index.d.ts +8 -2
  37. package/dist/safe-bash-mcp/index.js +13 -6
  38. package/package.json +7 -7
  39. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +62 -1
@@ -22706,6 +22706,2614 @@ var PageViewport = class _PageViewport {
22706
22706
  return p;
22707
22707
  }
22708
22708
  };
22709
+ function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) {
22710
+ const COMPONENTS = 3;
22711
+ alpha01 = alpha01 !== 1 ? 0 : alpha01;
22712
+ const xRatio = w1 / w2;
22713
+ const yRatio = h1 / h2;
22714
+ let newIndex = 0, oldIndex;
22715
+ const xScaled = new Uint16Array(w2);
22716
+ const w1Scanline = w1 * COMPONENTS;
22717
+ for (let i = 0; i < w2; i++) {
22718
+ xScaled[i] = Math.floor(i * xRatio) * COMPONENTS;
22719
+ }
22720
+ for (let i = 0; i < h2; i++) {
22721
+ const py = Math.floor(i * yRatio) * w1Scanline;
22722
+ for (let j = 0; j < w2; j++) {
22723
+ oldIndex = py + xScaled[j];
22724
+ dest[newIndex++] = src[oldIndex++];
22725
+ dest[newIndex++] = src[oldIndex++];
22726
+ dest[newIndex++] = src[oldIndex++];
22727
+ newIndex += alpha01;
22728
+ }
22729
+ }
22730
+ }
22731
+ function isDefaultDecodeHelper(decode, expectedLen) {
22732
+ if (!Array.isArray(decode)) {
22733
+ return true;
22734
+ }
22735
+ const decodeLen = decode.length;
22736
+ if (decodeLen < expectedLen) {
22737
+ warn2("Decode map length is too short.");
22738
+ return true;
22739
+ }
22740
+ if (decodeLen > expectedLen) {
22741
+ info("Truncating too long decode map.");
22742
+ decode.length = expectedLen;
22743
+ }
22744
+ return false;
22745
+ }
22746
+ var ColorSpace = class _ColorSpace {
22747
+ static #rgbBuf = new Uint8ClampedArray(3);
22748
+ constructor(name, numComps) {
22749
+ if ((typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) && this.constructor === _ColorSpace) {
22750
+ unreachable2("Cannot initialize ColorSpace.");
22751
+ }
22752
+ this.name = name;
22753
+ this.numComps = numComps;
22754
+ }
22755
+ /**
22756
+ * Converts the color value to the RGB color. The color components are
22757
+ * located in the src array starting from the srcOffset. Returns the array
22758
+ * of the rgb components, each value ranging from [0,255].
22759
+ */
22760
+ getRgb(src, srcOffset, output = new Uint8ClampedArray(3)) {
22761
+ this.getRgbItem(src, srcOffset, output, 0);
22762
+ return output;
22763
+ }
22764
+ getRgbHex(src, srcOffset) {
22765
+ const buffer = this.getRgb(src, srcOffset, _ColorSpace.#rgbBuf);
22766
+ return Util.makeHexColor(buffer[0], buffer[1], buffer[2]);
22767
+ }
22768
+ /**
22769
+ * Converts the color value to the RGB color, similar to the getRgb method.
22770
+ * The result placed into the dest array starting from the destOffset.
22771
+ */
22772
+ getRgbItem(src, srcOffset, dest, destOffset) {
22773
+ unreachable2("Should not call ColorSpace.getRgbItem");
22774
+ }
22775
+ /**
22776
+ * Converts the specified number of the color values to the RGB colors.
22777
+ * The colors are located in the src array starting from the srcOffset.
22778
+ * The result is placed into the dest array starting from the destOffset.
22779
+ * The src array items shall be in [0,2^bits) range, the dest array items
22780
+ * will be in [0,255] range. alpha01 indicates how many alpha components
22781
+ * there are in the dest array; it will be either 0 (RGB array) or 1 (RGBA
22782
+ * array).
22783
+ */
22784
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
22785
+ unreachable2("Should not call ColorSpace.getRgbBuffer");
22786
+ }
22787
+ /**
22788
+ * Converts `count` unscaled colors to RGB, starting at `destOffset`.
22789
+ * Components use the native color-space ranges expected by `getRgbItem`,
22790
+ * and each output has a `3 + alpha01` byte stride.
22791
+ * Subclasses may override this to batch expensive conversions.
22792
+ */
22793
+ getRgbItems(src, count, dest, destOffset, alpha01) {
22794
+ const { numComps } = this;
22795
+ for (let i = 0, srcOffset = 0; i < count; i++, srcOffset += numComps) {
22796
+ this.getRgbItem(src, srcOffset, dest, destOffset);
22797
+ destOffset += 3 + alpha01;
22798
+ }
22799
+ }
22800
+ /**
22801
+ * Returns true if source data will be equal the result/output data.
22802
+ */
22803
+ isPassthrough(bits) {
22804
+ return false;
22805
+ }
22806
+ /**
22807
+ * Refer to the static `ColorSpace.isDefaultDecode` method below.
22808
+ */
22809
+ isDefaultDecode(decode, bpc) {
22810
+ return _ColorSpace.isDefaultDecode(decode, this.numComps);
22811
+ }
22812
+ /**
22813
+ * Fills in the RGB colors in the destination buffer. alpha01 indicates
22814
+ * how many alpha components there are in the dest array; it will be either
22815
+ * 0 (RGB array) or 1 (RGBA array).
22816
+ */
22817
+ fillRgb(dest, originalWidth, originalHeight, width, height, actualHeight, bpc, comps, alpha01) {
22818
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
22819
+ assert2(
22820
+ dest instanceof Uint8ClampedArray,
22821
+ 'ColorSpace.fillRgb: Unsupported "dest" type.'
22822
+ );
22823
+ }
22824
+ const count = originalWidth * originalHeight;
22825
+ let rgbBuf = null;
22826
+ const numComponentColors = 1 << bpc;
22827
+ const needsResizing = originalHeight !== height || originalWidth !== width;
22828
+ if (this.isPassthrough(bpc)) {
22829
+ rgbBuf = comps;
22830
+ } else if (this.numComps === 1 && count > numComponentColors && this.name !== "DeviceGray" && this.name !== "DeviceRGB") {
22831
+ const allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : new Uint16Array(numComponentColors);
22832
+ for (let i = 0; i < numComponentColors; i++) {
22833
+ allColors[i] = i;
22834
+ }
22835
+ const colorMap = new Uint8ClampedArray(numComponentColors * 3);
22836
+ this.getRgbBuffer(
22837
+ allColors,
22838
+ 0,
22839
+ numComponentColors,
22840
+ colorMap,
22841
+ 0,
22842
+ bpc,
22843
+ /* alpha01 = */
22844
+ 0
22845
+ );
22846
+ if (!needsResizing) {
22847
+ let destPos = 0;
22848
+ for (let i = 0; i < count; ++i) {
22849
+ const key = comps[i] * 3;
22850
+ dest[destPos++] = colorMap[key];
22851
+ dest[destPos++] = colorMap[key + 1];
22852
+ dest[destPos++] = colorMap[key + 2];
22853
+ destPos += alpha01;
22854
+ }
22855
+ } else {
22856
+ rgbBuf = new Uint8Array(count * 3);
22857
+ let rgbPos = 0;
22858
+ for (let i = 0; i < count; ++i) {
22859
+ const key = comps[i] * 3;
22860
+ rgbBuf[rgbPos++] = colorMap[key];
22861
+ rgbBuf[rgbPos++] = colorMap[key + 1];
22862
+ rgbBuf[rgbPos++] = colorMap[key + 2];
22863
+ }
22864
+ }
22865
+ } else if (!needsResizing) {
22866
+ this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, alpha01);
22867
+ } else {
22868
+ rgbBuf = new Uint8ClampedArray(count * 3);
22869
+ this.getRgbBuffer(
22870
+ comps,
22871
+ 0,
22872
+ count,
22873
+ rgbBuf,
22874
+ 0,
22875
+ bpc,
22876
+ /* alpha01 = */
22877
+ 0
22878
+ );
22879
+ }
22880
+ if (rgbBuf) {
22881
+ if (needsResizing) {
22882
+ resizeRgbImage(
22883
+ rgbBuf,
22884
+ dest,
22885
+ originalWidth,
22886
+ originalHeight,
22887
+ width,
22888
+ height,
22889
+ alpha01
22890
+ );
22891
+ } else {
22892
+ let destPos = 0, rgbPos = 0;
22893
+ for (let i = 0, ii = width * actualHeight; i < ii; i++) {
22894
+ dest[destPos++] = rgbBuf[rgbPos++];
22895
+ dest[destPos++] = rgbBuf[rgbPos++];
22896
+ dest[destPos++] = rgbBuf[rgbPos++];
22897
+ destPos += alpha01;
22898
+ }
22899
+ }
22900
+ }
22901
+ }
22902
+ /**
22903
+ * True if the colorspace has components in the default range of [0, 1].
22904
+ * This should be true for all colorspaces except for lab color spaces
22905
+ * which are [0,100], [-128, 127], [-128, 127].
22906
+ */
22907
+ get usesZeroToOneRange() {
22908
+ return shadow2(this, "usesZeroToOneRange", true);
22909
+ }
22910
+ /**
22911
+ * Checks if a decode map matches the default decode map for a color space.
22912
+ * This handles the general decode maps where there are two values per
22913
+ * component, e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
22914
+ * This does not handle Lab, Indexed, or Pattern decode maps since they are
22915
+ * slightly different.
22916
+ * @param {Array} decode - Decode map (usually from an image).
22917
+ * @param {number} numComps - Number of components the color space has.
22918
+ */
22919
+ static isDefaultDecode(decode, numComps) {
22920
+ if (isDefaultDecodeHelper(decode, numComps * 2)) {
22921
+ return true;
22922
+ }
22923
+ for (let i = 0, ii = decode.length; i < ii; i += 2) {
22924
+ if (decode[i] !== 0 || decode[i + 1] !== 1) {
22925
+ return false;
22926
+ }
22927
+ }
22928
+ return true;
22929
+ }
22930
+ };
22931
+ var DeviceCmykCS = class extends ColorSpace {
22932
+ constructor() {
22933
+ super("DeviceCMYK", 4);
22934
+ }
22935
+ // The coefficients below was found using numerical analysis: the method of
22936
+ // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors,
22937
+ // where color_value is the tabular value from the table of sampled RGB colors
22938
+ // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding
22939
+ // CMYK color conversion using the estimation below:
22940
+ // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255
22941
+ #toRgb(src, srcOffset, srcScale, dest, destOffset) {
22942
+ const c = src[srcOffset] * srcScale;
22943
+ const m = src[srcOffset + 1] * srcScale;
22944
+ const y = src[srcOffset + 2] * srcScale;
22945
+ const k = src[srcOffset + 3] * srcScale;
22946
+ dest[destOffset] = 255 + c * (-4.387332384609988 * c + 54.48615194189176 * m + 18.82290502165302 * y + 212.25662451639585 * k + -285.2331026137004) + m * (1.7149763477362134 * m - 5.6096736904047315 * y + -17.873870861415444 * k - 5.497006427196366) + y * (-2.5217340131683033 * y - 21.248923337353073 * k + 17.5119270841813) + k * (-21.86122147463605 * k - 189.48180835922747);
22947
+ dest[destOffset + 1] = 255 + c * (8.841041422036149 * c + 60.118027045597366 * m + 6.871425592049007 * y + 31.159100130055922 * k + -79.2970844816548) + m * (-15.310361306967817 * m + 17.575251261109482 * y + 131.35250912493976 * k - 190.9453302588951) + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) + k * (-20.737325471181034 * k - 187.80453709719578);
22948
+ dest[destOffset + 2] = 255 + c * (0.8842522430003296 * c + 8.078677503112928 * m + 30.89978309703729 * y - 0.23883238689178934 * k + -14.183576799673286) + m * (10.49593273432072 * m + 63.02378494754052 * y + 50.606957656360734 * k - 112.23884253719248) + y * (0.03296041114873217 * y + 115.60384449646641 * k + -193.58209356861505) + k * (-22.33816807309886 * k - 180.12613974708367);
22949
+ }
22950
+ getRgbItem(src, srcOffset, dest, destOffset) {
22951
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
22952
+ assert2(
22953
+ dest instanceof Uint8ClampedArray,
22954
+ 'DeviceCmykCS.getRgbItem: Unsupported "dest" type.'
22955
+ );
22956
+ }
22957
+ this.#toRgb(src, srcOffset, 1, dest, destOffset);
22958
+ }
22959
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
22960
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
22961
+ assert2(
22962
+ dest instanceof Uint8ClampedArray,
22963
+ 'DeviceCmykCS.getRgbBuffer: Unsupported "dest" type.'
22964
+ );
22965
+ }
22966
+ const scale = 1 / ((1 << bits) - 1);
22967
+ for (let i = 0; i < count; i++) {
22968
+ this.#toRgb(src, srcOffset, scale, dest, destOffset);
22969
+ srcOffset += 4;
22970
+ destOffset += 3 + alpha01;
22971
+ }
22972
+ }
22973
+ };
22974
+ var CalGrayCS = class extends ColorSpace {
22975
+ constructor(whitePoint, blackPoint, gamma) {
22976
+ super("CalGray", 1);
22977
+ if (!whitePoint) {
22978
+ throw new FormatError(
22979
+ "WhitePoint missing - required for color space CalGray"
22980
+ );
22981
+ }
22982
+ [this.XW, this.YW, this.ZW] = whitePoint;
22983
+ [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];
22984
+ this.G = gamma || 1;
22985
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
22986
+ throw new FormatError(
22987
+ `Invalid WhitePoint components for ${this.name}, no fallback available`
22988
+ );
22989
+ }
22990
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
22991
+ info(`Invalid BlackPoint for ${this.name}, falling back to default.`);
22992
+ this.XB = this.YB = this.ZB = 0;
22993
+ }
22994
+ if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
22995
+ warn2(
22996
+ `${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ZB: ${this.ZB}, only default values are supported.`
22997
+ );
22998
+ }
22999
+ if (this.G < 1) {
23000
+ info(
23001
+ `Invalid Gamma: ${this.G} for ${this.name}, falling back to default.`
23002
+ );
23003
+ this.G = 1;
23004
+ }
23005
+ }
23006
+ #toRgb(src, srcOffset, dest, destOffset, scale) {
23007
+ const A = src[srcOffset] * scale;
23008
+ const AG = A ** this.G;
23009
+ const L = this.YW * AG;
23010
+ const val = Math.max(295.8 * L ** 0.3333333333333333 - 40.8, 0);
23011
+ dest[destOffset] = val;
23012
+ dest[destOffset + 1] = val;
23013
+ dest[destOffset + 2] = val;
23014
+ }
23015
+ getRgbItem(src, srcOffset, dest, destOffset) {
23016
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
23017
+ assert2(
23018
+ dest instanceof Uint8ClampedArray,
23019
+ 'CalGrayCS.getRgbItem: Unsupported "dest" type.'
23020
+ );
23021
+ }
23022
+ this.#toRgb(src, srcOffset, dest, destOffset, 1);
23023
+ }
23024
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
23025
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
23026
+ assert2(
23027
+ dest instanceof Uint8ClampedArray,
23028
+ 'CalGrayCS.getRgbBuffer: Unsupported "dest" type.'
23029
+ );
23030
+ }
23031
+ const scale = 1 / ((1 << bits) - 1);
23032
+ for (let i = 0; i < count; ++i) {
23033
+ this.#toRgb(src, srcOffset, dest, destOffset, scale);
23034
+ srcOffset += 1;
23035
+ destOffset += 3 + alpha01;
23036
+ }
23037
+ }
23038
+ };
23039
+ var CalRGBCS = class _CalRGBCS extends ColorSpace {
23040
+ // See http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html for these
23041
+ // matrices.
23042
+ // prettier-ignore
23043
+ static #BRADFORD_SCALE_MATRIX = new Float32Array([
23044
+ 0.8951,
23045
+ 0.2664,
23046
+ -0.1614,
23047
+ -0.7502,
23048
+ 1.7135,
23049
+ 0.0367,
23050
+ 0.0389,
23051
+ -0.0685,
23052
+ 1.0296
23053
+ ]);
23054
+ // prettier-ignore
23055
+ static #BRADFORD_SCALE_INVERSE_MATRIX = new Float32Array([
23056
+ 0.9869929,
23057
+ -0.1470543,
23058
+ 0.1599627,
23059
+ 0.4323053,
23060
+ 0.5183603,
23061
+ 0.0492912,
23062
+ -85287e-7,
23063
+ 0.0400428,
23064
+ 0.9684867
23065
+ ]);
23066
+ // See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html.
23067
+ // prettier-ignore
23068
+ static #SRGB_D65_XYZ_TO_RGB_MATRIX = new Float32Array([
23069
+ 3.2404542,
23070
+ -1.5371385,
23071
+ -0.4985314,
23072
+ -0.969266,
23073
+ 1.8760108,
23074
+ 0.041556,
23075
+ 0.0556434,
23076
+ -0.2040259,
23077
+ 1.0572252
23078
+ ]);
23079
+ static #FLAT_WHITEPOINT_MATRIX = new Float32Array([1, 1, 1]);
23080
+ static #tempNormalizeMatrix = new Float32Array(3);
23081
+ static #tempConvertMatrix1 = new Float32Array(3);
23082
+ static #tempConvertMatrix2 = new Float32Array(3);
23083
+ static #DECODE_L_CONSTANT = ((8 + 16) / 116) ** 3 / 8;
23084
+ constructor(whitePoint, blackPoint, gamma, matrix) {
23085
+ super("CalRGB", 3);
23086
+ if (!whitePoint) {
23087
+ throw new FormatError(
23088
+ "WhitePoint missing - required for color space CalRGB"
23089
+ );
23090
+ }
23091
+ const [XW, YW, ZW] = this.whitePoint = whitePoint;
23092
+ const [XB, YB, ZB] = this.blackPoint = blackPoint || new Float32Array(3);
23093
+ [this.GR, this.GG, this.GB] = gamma || new Float32Array([1, 1, 1]);
23094
+ [
23095
+ this.MXA,
23096
+ this.MYA,
23097
+ this.MZA,
23098
+ this.MXB,
23099
+ this.MYB,
23100
+ this.MZB,
23101
+ this.MXC,
23102
+ this.MYC,
23103
+ this.MZC
23104
+ ] = matrix || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);
23105
+ if (XW < 0 || ZW < 0 || YW !== 1) {
23106
+ throw new FormatError(
23107
+ `Invalid WhitePoint components for ${this.name}, no fallback available`
23108
+ );
23109
+ }
23110
+ if (XB < 0 || YB < 0 || ZB < 0) {
23111
+ info(
23112
+ `Invalid BlackPoint for ${this.name} [${XB}, ${YB}, ${ZB}], falling back to default.`
23113
+ );
23114
+ this.blackPoint = new Float32Array(3);
23115
+ }
23116
+ if (this.GR < 0 || this.GG < 0 || this.GB < 0) {
23117
+ info(
23118
+ `Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ${this.name}, falling back to default.`
23119
+ );
23120
+ this.GR = this.GG = this.GB = 1;
23121
+ }
23122
+ }
23123
+ #matrixProduct(a, b, result) {
23124
+ result[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
23125
+ result[1] = a[3] * b[0] + a[4] * b[1] + a[5] * b[2];
23126
+ result[2] = a[6] * b[0] + a[7] * b[1] + a[8] * b[2];
23127
+ }
23128
+ #toFlat(sourceWhitePoint, LMS, result) {
23129
+ result[0] = LMS[0] * 1 / sourceWhitePoint[0];
23130
+ result[1] = LMS[1] * 1 / sourceWhitePoint[1];
23131
+ result[2] = LMS[2] * 1 / sourceWhitePoint[2];
23132
+ }
23133
+ #toD65(sourceWhitePoint, LMS, result) {
23134
+ const D65X = 0.95047;
23135
+ const D65Y = 1;
23136
+ const D65Z = 1.08883;
23137
+ result[0] = LMS[0] * D65X / sourceWhitePoint[0];
23138
+ result[1] = LMS[1] * D65Y / sourceWhitePoint[1];
23139
+ result[2] = LMS[2] * D65Z / sourceWhitePoint[2];
23140
+ }
23141
+ #sRGBTransferFunction(color) {
23142
+ if (color <= 31308e-7) {
23143
+ return MathClamp(12.92 * color, 0, 1);
23144
+ }
23145
+ return color >= 0.99554525 ? 1 : MathClamp((1 + 0.055) * color ** (1 / 2.4) - 0.055, 0, 1);
23146
+ }
23147
+ #decodeL(L) {
23148
+ if (L < 0) {
23149
+ return -this.#decodeL(-L);
23150
+ }
23151
+ return L > 8 ? ((L + 16) / 116) ** 3 : L * _CalRGBCS.#DECODE_L_CONSTANT;
23152
+ }
23153
+ #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) {
23154
+ if (sourceBlackPoint[0] === 0 && sourceBlackPoint[1] === 0 && sourceBlackPoint[2] === 0) {
23155
+ result[0] = XYZ_Flat[0];
23156
+ result[1] = XYZ_Flat[1];
23157
+ result[2] = XYZ_Flat[2];
23158
+ return;
23159
+ }
23160
+ const zeroDecodeL = this.#decodeL(0);
23161
+ const X_DST = zeroDecodeL;
23162
+ const X_SRC = this.#decodeL(sourceBlackPoint[0]);
23163
+ const Y_DST = zeroDecodeL;
23164
+ const Y_SRC = this.#decodeL(sourceBlackPoint[1]);
23165
+ const Z_DST = zeroDecodeL;
23166
+ const Z_SRC = this.#decodeL(sourceBlackPoint[2]);
23167
+ const X_Scale = (1 - X_DST) / (1 - X_SRC);
23168
+ const X_Offset = 1 - X_Scale;
23169
+ const Y_Scale = (1 - Y_DST) / (1 - Y_SRC);
23170
+ const Y_Offset = 1 - Y_Scale;
23171
+ const Z_Scale = (1 - Z_DST) / (1 - Z_SRC);
23172
+ const Z_Offset = 1 - Z_Scale;
23173
+ result[0] = XYZ_Flat[0] * X_Scale + X_Offset;
23174
+ result[1] = XYZ_Flat[1] * Y_Scale + Y_Offset;
23175
+ result[2] = XYZ_Flat[2] * Z_Scale + Z_Offset;
23176
+ }
23177
+ #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) {
23178
+ if (sourceWhitePoint[0] === 1 && sourceWhitePoint[2] === 1) {
23179
+ result[0] = XYZ_In[0];
23180
+ result[1] = XYZ_In[1];
23181
+ result[2] = XYZ_In[2];
23182
+ return;
23183
+ }
23184
+ const LMS = result;
23185
+ this.#matrixProduct(_CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);
23186
+ const LMS_Flat = _CalRGBCS.#tempNormalizeMatrix;
23187
+ this.#toFlat(sourceWhitePoint, LMS, LMS_Flat);
23188
+ this.#matrixProduct(
23189
+ _CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX,
23190
+ LMS_Flat,
23191
+ result
23192
+ );
23193
+ }
23194
+ #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) {
23195
+ const LMS = result;
23196
+ this.#matrixProduct(_CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);
23197
+ const LMS_D65 = _CalRGBCS.#tempNormalizeMatrix;
23198
+ this.#toD65(sourceWhitePoint, LMS, LMS_D65);
23199
+ this.#matrixProduct(
23200
+ _CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX,
23201
+ LMS_D65,
23202
+ result
23203
+ );
23204
+ }
23205
+ #toRgb(src, srcOffset, dest, destOffset, scale) {
23206
+ const A = MathClamp(src[srcOffset] * scale, 0, 1);
23207
+ const B = MathClamp(src[srcOffset + 1] * scale, 0, 1);
23208
+ const C = MathClamp(src[srcOffset + 2] * scale, 0, 1);
23209
+ const AGR = A === 1 ? 1 : A ** this.GR;
23210
+ const BGG = B === 1 ? 1 : B ** this.GG;
23211
+ const CGB = C === 1 ? 1 : C ** this.GB;
23212
+ const X = this.MXA * AGR + this.MXB * BGG + this.MXC * CGB;
23213
+ const Y = this.MYA * AGR + this.MYB * BGG + this.MYC * CGB;
23214
+ const Z = this.MZA * AGR + this.MZB * BGG + this.MZC * CGB;
23215
+ const XYZ = _CalRGBCS.#tempConvertMatrix1;
23216
+ XYZ[0] = X;
23217
+ XYZ[1] = Y;
23218
+ XYZ[2] = Z;
23219
+ const XYZ_Flat = _CalRGBCS.#tempConvertMatrix2;
23220
+ this.#normalizeWhitePointToFlat(this.whitePoint, XYZ, XYZ_Flat);
23221
+ const XYZ_Black = _CalRGBCS.#tempConvertMatrix1;
23222
+ this.#compensateBlackPoint(this.blackPoint, XYZ_Flat, XYZ_Black);
23223
+ const XYZ_D65 = _CalRGBCS.#tempConvertMatrix2;
23224
+ this.#normalizeWhitePointToD65(
23225
+ _CalRGBCS.#FLAT_WHITEPOINT_MATRIX,
23226
+ XYZ_Black,
23227
+ XYZ_D65
23228
+ );
23229
+ const SRGB = _CalRGBCS.#tempConvertMatrix1;
23230
+ this.#matrixProduct(_CalRGBCS.#SRGB_D65_XYZ_TO_RGB_MATRIX, XYZ_D65, SRGB);
23231
+ dest[destOffset] = this.#sRGBTransferFunction(SRGB[0]) * 255;
23232
+ dest[destOffset + 1] = this.#sRGBTransferFunction(SRGB[1]) * 255;
23233
+ dest[destOffset + 2] = this.#sRGBTransferFunction(SRGB[2]) * 255;
23234
+ }
23235
+ getRgbItem(src, srcOffset, dest, destOffset) {
23236
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
23237
+ assert2(
23238
+ dest instanceof Uint8ClampedArray,
23239
+ 'CalRGBCS.getRgbItem: Unsupported "dest" type.'
23240
+ );
23241
+ }
23242
+ this.#toRgb(src, srcOffset, dest, destOffset, 1);
23243
+ }
23244
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
23245
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
23246
+ assert2(
23247
+ dest instanceof Uint8ClampedArray,
23248
+ 'CalRGBCS.getRgbBuffer: Unsupported "dest" type.'
23249
+ );
23250
+ }
23251
+ const scale = 1 / ((1 << bits) - 1);
23252
+ for (let i = 0; i < count; ++i) {
23253
+ this.#toRgb(src, srcOffset, dest, destOffset, scale);
23254
+ srcOffset += 3;
23255
+ destOffset += 3 + alpha01;
23256
+ }
23257
+ }
23258
+ };
23259
+ var LabCS = class extends ColorSpace {
23260
+ constructor(whitePoint, blackPoint, range) {
23261
+ super("Lab", 3);
23262
+ if (!whitePoint) {
23263
+ throw new FormatError(
23264
+ "WhitePoint missing - required for color space Lab"
23265
+ );
23266
+ }
23267
+ [this.XW, this.YW, this.ZW] = whitePoint;
23268
+ [this.amin, this.amax, this.bmin, this.bmax] = range || [
23269
+ -100,
23270
+ 100,
23271
+ -100,
23272
+ 100
23273
+ ];
23274
+ [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];
23275
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
23276
+ throw new FormatError(
23277
+ "Invalid WhitePoint components, no fallback available"
23278
+ );
23279
+ }
23280
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
23281
+ info("Invalid BlackPoint, falling back to default");
23282
+ this.XB = this.YB = this.ZB = 0;
23283
+ }
23284
+ if (this.amin > this.amax || this.bmin > this.bmax) {
23285
+ info("Invalid Range, falling back to defaults");
23286
+ this.amin = -100;
23287
+ this.amax = 100;
23288
+ this.bmin = -100;
23289
+ this.bmax = 100;
23290
+ }
23291
+ }
23292
+ // Function g(x) from spec
23293
+ #fn_g(x) {
23294
+ return x >= 6 / 29 ? x ** 3 : 108 / 841 * (x - 4 / 29);
23295
+ }
23296
+ #decode(value, high1, low2, high2) {
23297
+ return low2 + value * (high2 - low2) / high1;
23298
+ }
23299
+ // If decoding is needed maxVal should be 2^bits per component - 1.
23300
+ #toRgb(src, srcOffset, maxVal, dest, destOffset) {
23301
+ let Ls = src[srcOffset];
23302
+ let as = src[srcOffset + 1];
23303
+ let bs = src[srcOffset + 2];
23304
+ if (maxVal !== false) {
23305
+ Ls = this.#decode(Ls, maxVal, 0, 100);
23306
+ as = this.#decode(as, maxVal, this.amin, this.amax);
23307
+ bs = this.#decode(bs, maxVal, this.bmin, this.bmax);
23308
+ }
23309
+ if (as > this.amax) {
23310
+ as = this.amax;
23311
+ } else if (as < this.amin) {
23312
+ as = this.amin;
23313
+ }
23314
+ if (bs > this.bmax) {
23315
+ bs = this.bmax;
23316
+ } else if (bs < this.bmin) {
23317
+ bs = this.bmin;
23318
+ }
23319
+ const M = (Ls + 16) / 116;
23320
+ const L = M + as / 500;
23321
+ const N = M - bs / 200;
23322
+ const X = this.XW * this.#fn_g(L);
23323
+ const Y = this.YW * this.#fn_g(M);
23324
+ const Z = this.ZW * this.#fn_g(N);
23325
+ let r, g, b;
23326
+ if (this.ZW < 1) {
23327
+ r = X * 3.1339 + Y * -1.617 + Z * -0.4906;
23328
+ g = X * -0.9785 + Y * 1.916 + Z * 0.0333;
23329
+ b = X * 0.072 + Y * -0.229 + Z * 1.4057;
23330
+ } else {
23331
+ r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
23332
+ g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
23333
+ b = X * 0.0557 + Y * -0.204 + Z * 1.057;
23334
+ }
23335
+ dest[destOffset] = Math.sqrt(r) * 255;
23336
+ dest[destOffset + 1] = Math.sqrt(g) * 255;
23337
+ dest[destOffset + 2] = Math.sqrt(b) * 255;
23338
+ }
23339
+ getRgbItem(src, srcOffset, dest, destOffset) {
23340
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
23341
+ assert2(
23342
+ dest instanceof Uint8ClampedArray,
23343
+ 'LabCS.getRgbItem: Unsupported "dest" type.'
23344
+ );
23345
+ }
23346
+ this.#toRgb(src, srcOffset, false, dest, destOffset);
23347
+ }
23348
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
23349
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
23350
+ assert2(
23351
+ dest instanceof Uint8ClampedArray,
23352
+ 'LabCS.getRgbBuffer: Unsupported "dest" type.'
23353
+ );
23354
+ }
23355
+ const maxVal = (1 << bits) - 1;
23356
+ for (let i = 0; i < count; i++) {
23357
+ this.#toRgb(src, srcOffset, maxVal, dest, destOffset);
23358
+ srcOffset += 3;
23359
+ destOffset += 3 + alpha01;
23360
+ }
23361
+ }
23362
+ isDefaultDecode(decode, bpc) {
23363
+ return true;
23364
+ }
23365
+ get usesZeroToOneRange() {
23366
+ return shadow2(this, "usesZeroToOneRange", false);
23367
+ }
23368
+ };
23369
+ var TOKEN = {
23370
+ // Structural tokens — not keyword operators
23371
+ number: 0,
23372
+ lbrace: 1,
23373
+ rbrace: 2,
23374
+ // Boolean literals
23375
+ true: 3,
23376
+ false: 4,
23377
+ // Arithmetic binary operators
23378
+ add: 5,
23379
+ sub: 6,
23380
+ mul: 7,
23381
+ div: 8,
23382
+ idiv: 9,
23383
+ mod: 10,
23384
+ exp: 11,
23385
+ // Comparison binary operators
23386
+ eq: 12,
23387
+ ne: 13,
23388
+ gt: 14,
23389
+ ge: 15,
23390
+ lt: 16,
23391
+ le: 17,
23392
+ // Bitwise / boolean binary operators
23393
+ and: 18,
23394
+ or: 19,
23395
+ xor: 20,
23396
+ bitshift: 21,
23397
+ // Unary arithmetic operators
23398
+ abs: 22,
23399
+ neg: 23,
23400
+ ceiling: 24,
23401
+ floor: 25,
23402
+ round: 26,
23403
+ truncate: 27,
23404
+ // Unary boolean / bitwise operator
23405
+ not: 28,
23406
+ // Mathematical functions — unary
23407
+ sqrt: 29,
23408
+ sin: 30,
23409
+ cos: 31,
23410
+ ln: 32,
23411
+ log: 33,
23412
+ // Mathematical function — binary
23413
+ atan: 34,
23414
+ // Type conversion operators
23415
+ cvi: 35,
23416
+ cvr: 36,
23417
+ // Stack operators
23418
+ dup: 37,
23419
+ exch: 38,
23420
+ pop: 39,
23421
+ copy: 40,
23422
+ index: 41,
23423
+ roll: 42,
23424
+ // Control flow
23425
+ if: 43,
23426
+ ifelse: 44,
23427
+ // End of input
23428
+ eof: 45,
23429
+ // Synthetic: produced by the optimizer, never emitted by the lexer.
23430
+ min: 46,
23431
+ max: 47
23432
+ };
23433
+ var Token = class {
23434
+ constructor(id, value = null) {
23435
+ this.id = id;
23436
+ this.value = value;
23437
+ }
23438
+ };
23439
+ var Lexer = class _Lexer {
23440
+ // Singletons for every non-number token, built lazily on first construction.
23441
+ // Keyword operator tokens carry their name as `value`; structural tokens
23442
+ // (lbrace, rbrace, eof) carry null.
23443
+ static #singletons = null;
23444
+ static #operatorSingletons = null;
23445
+ static #initSingletons() {
23446
+ const singletons = /* @__PURE__ */ Object.create(null);
23447
+ const operatorSingletons = /* @__PURE__ */ Object.create(null);
23448
+ for (const [name, id] of Object.entries(TOKEN)) {
23449
+ if (name === "number") {
23450
+ continue;
23451
+ }
23452
+ const isOperator = id >= TOKEN.true && id <= TOKEN.ifelse;
23453
+ const token = new Token(id, isOperator ? name : null);
23454
+ singletons[name] = token;
23455
+ if (isOperator) {
23456
+ operatorSingletons[name] = token;
23457
+ }
23458
+ }
23459
+ this.#singletons = singletons;
23460
+ this.#operatorSingletons = operatorSingletons;
23461
+ }
23462
+ constructor(data) {
23463
+ if (!_Lexer.#singletons) {
23464
+ _Lexer.#initSingletons();
23465
+ }
23466
+ this.data = data;
23467
+ this.pos = 0;
23468
+ this.len = data.length;
23469
+ this._numberPattern = /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/iy;
23470
+ this._identifierPattern = /[a-z]+/y;
23471
+ }
23472
+ // Skip a % comment, advancing past the next \n or \r (or to EOF).
23473
+ _skipComment() {
23474
+ const lf = this.data.indexOf("\n", this.pos);
23475
+ const cr = this.data.indexOf("\r", this.pos);
23476
+ const eol = Math.min(lf < 0 ? this.len : lf, cr < 0 ? this.len : cr);
23477
+ this.pos = Math.min(eol + 1, this.len);
23478
+ }
23479
+ _getNumber() {
23480
+ this._numberPattern.lastIndex = this.pos;
23481
+ const match = this._numberPattern.exec(this.data);
23482
+ if (!match) {
23483
+ return new Token(TOKEN.number, 0);
23484
+ }
23485
+ const number = parseFloat(match[0]);
23486
+ if (!Number.isFinite(number)) {
23487
+ return new Token(TOKEN.number, 0);
23488
+ }
23489
+ this.pos = this._numberPattern.lastIndex;
23490
+ return new Token(TOKEN.number, number);
23491
+ }
23492
+ _getOperator() {
23493
+ this._identifierPattern.lastIndex = this.pos;
23494
+ const match = this._identifierPattern.exec(this.data);
23495
+ if (!match) {
23496
+ return new Token(TOKEN.number, 0);
23497
+ }
23498
+ this.pos = this._identifierPattern.lastIndex;
23499
+ const op = match[0];
23500
+ const token = _Lexer.#operatorSingletons[op];
23501
+ return token ?? new Token(TOKEN.number, 0);
23502
+ }
23503
+ // Return the next token, or Lexer.#singletons.eof at end of input.
23504
+ next() {
23505
+ while (this.pos < this.len) {
23506
+ const ch3 = this.data.charCodeAt(this.pos++);
23507
+ switch (ch3) {
23508
+ // PostScript white-space characters (PDF32000 §7.2.2)
23509
+ case 0:
23510
+ case 9:
23511
+ case 10:
23512
+ case 12:
23513
+ case 13:
23514
+ case 32:
23515
+ break;
23516
+ case 37:
23517
+ this._skipComment();
23518
+ break;
23519
+ case 123:
23520
+ return _Lexer.#singletons.lbrace;
23521
+ case 125:
23522
+ return _Lexer.#singletons.rbrace;
23523
+ case 43:
23524
+ case 45:
23525
+ this.pos--;
23526
+ return this._getNumber();
23527
+ case 46:
23528
+ this.pos--;
23529
+ return this._getNumber();
23530
+ default:
23531
+ if (ch3 >= 48 && ch3 <= 57) {
23532
+ this.pos--;
23533
+ return this._getNumber();
23534
+ }
23535
+ if (ch3 >= 97 && ch3 <= 122) {
23536
+ this.pos--;
23537
+ return this._getOperator();
23538
+ }
23539
+ return new Token(TOKEN.number, 0);
23540
+ }
23541
+ }
23542
+ return _Lexer.#singletons.eof;
23543
+ }
23544
+ };
23545
+ var PS_VALUE_TYPE = {
23546
+ numeric: 0,
23547
+ // known to be a number (f64 in Wasm)
23548
+ boolean: 1,
23549
+ // known to be a boolean (0.0 = false, 1.0 = true in f64)
23550
+ unknown: 2
23551
+ // indeterminate at compile time
23552
+ };
23553
+ var PS_NODE = {
23554
+ // Parser AST node types (produced by Parser / parsePostScriptFunction)
23555
+ program: 0,
23556
+ block: 1,
23557
+ number: 2,
23558
+ operator: 3,
23559
+ if: 4,
23560
+ ifelse: 5,
23561
+ // Tree AST node types (produced by PSStackToTree)
23562
+ arg: 6,
23563
+ const: 7,
23564
+ unary: 8,
23565
+ binary: 9,
23566
+ ternary: 10
23567
+ };
23568
+ var PsNode = class {
23569
+ constructor(type) {
23570
+ this.type = type;
23571
+ }
23572
+ };
23573
+ var PsProgram = class extends PsNode {
23574
+ constructor(body) {
23575
+ super(PS_NODE.program);
23576
+ this.body = body;
23577
+ }
23578
+ };
23579
+ var PsBlock = class extends PsNode {
23580
+ constructor(instructions) {
23581
+ super(PS_NODE.block);
23582
+ this.instructions = instructions;
23583
+ }
23584
+ };
23585
+ var PsNumber = class extends PsNode {
23586
+ /** @param {number} value */
23587
+ constructor(value) {
23588
+ super(PS_NODE.number);
23589
+ this.value = value;
23590
+ }
23591
+ };
23592
+ var PsOperator = class extends PsNode {
23593
+ /** @param {number} op — one of the TOKEN.* constants from lexer.js */
23594
+ constructor(op) {
23595
+ super(PS_NODE.operator);
23596
+ this.op = op;
23597
+ }
23598
+ };
23599
+ var PsIf = class extends PsNode {
23600
+ /** @param {PsBlock} then */
23601
+ constructor(then) {
23602
+ super(PS_NODE.if);
23603
+ this.then = then;
23604
+ }
23605
+ };
23606
+ var PsIfElse = class extends PsNode {
23607
+ /**
23608
+ * @param {PsBlock} then
23609
+ * @param {PsBlock} otherwise
23610
+ */
23611
+ constructor(then, otherwise) {
23612
+ super(PS_NODE.ifelse);
23613
+ this.then = then;
23614
+ this.otherwise = otherwise;
23615
+ }
23616
+ };
23617
+ var PsArgNode = class extends PsNode {
23618
+ /** @param {number} index */
23619
+ constructor(index) {
23620
+ super(PS_NODE.arg);
23621
+ this.index = index;
23622
+ this.valueType = PS_VALUE_TYPE.numeric;
23623
+ }
23624
+ };
23625
+ var PsConstNode = class extends PsNode {
23626
+ /** @param {number|boolean} value */
23627
+ constructor(value) {
23628
+ super(PS_NODE.const);
23629
+ this.value = value;
23630
+ this.valueType = typeof value === "boolean" ? PS_VALUE_TYPE.boolean : PS_VALUE_TYPE.numeric;
23631
+ }
23632
+ };
23633
+ var PsUnaryNode = class extends PsNode {
23634
+ /**
23635
+ * @param {number} op — TOKEN.* constant
23636
+ * @param {PsNode} operand
23637
+ * @param {number} [valueType]
23638
+ */
23639
+ constructor(op, operand, valueType = PS_VALUE_TYPE.unknown) {
23640
+ super(PS_NODE.unary);
23641
+ this.op = op;
23642
+ this.operand = operand;
23643
+ this.valueType = valueType;
23644
+ }
23645
+ };
23646
+ var PsBinaryNode = class extends PsNode {
23647
+ /**
23648
+ * @param {number} op — TOKEN.* constant
23649
+ * @param {PsNode} first — was on top of stack
23650
+ * @param {PsNode} second — was below top
23651
+ * @param {number} [valueType]
23652
+ */
23653
+ constructor(op, first, second, valueType = PS_VALUE_TYPE.unknown) {
23654
+ super(PS_NODE.binary);
23655
+ this.op = op;
23656
+ this.first = first;
23657
+ this.second = second;
23658
+ this.valueType = valueType;
23659
+ }
23660
+ };
23661
+ var PsTernaryNode = class extends PsNode {
23662
+ /**
23663
+ * @param {PsNode} cond
23664
+ * @param {PsNode} then
23665
+ * @param {PsNode} otherwise
23666
+ * @param {number} [valueType]
23667
+ */
23668
+ constructor(cond, then, otherwise, valueType = PS_VALUE_TYPE.unknown) {
23669
+ super(PS_NODE.ternary);
23670
+ this.cond = cond;
23671
+ this.then = then;
23672
+ this.otherwise = otherwise;
23673
+ this.valueType = valueType;
23674
+ }
23675
+ };
23676
+ var Parser = class _Parser {
23677
+ constructor(lexer) {
23678
+ this.lexer = lexer;
23679
+ this._token = null;
23680
+ }
23681
+ static _isRegularOperator(id) {
23682
+ return id >= TOKEN.true && id < TOKEN.if;
23683
+ }
23684
+ // Fetch the next token from the lexer.
23685
+ _advance() {
23686
+ this._token = this.lexer.next();
23687
+ }
23688
+ // Assert that the current token has the given id, consume it, and return it.
23689
+ _expect(id) {
23690
+ if (this._token.id !== id) {
23691
+ throw new FormatError(
23692
+ `PostScript function: expected token id ${id}, got ${this._token.id}.`
23693
+ );
23694
+ }
23695
+ const tok = this._token;
23696
+ this._advance();
23697
+ return tok;
23698
+ }
23699
+ /**
23700
+ * Parse the full Type 4 function body.
23701
+ *
23702
+ * Grammar (simplified):
23703
+ * program ::= '{' block '}'
23704
+ * block ::= instruction*
23705
+ * instruction ::= number
23706
+ * | operator (any PS_OPERATOR except if / ifelse)
23707
+ * | '{' block '}' 'if'
23708
+ * | '{' block '}' '{' block '}' 'ifelse'
23709
+ * @returns {PsProgram}
23710
+ */
23711
+ parse() {
23712
+ this._advance();
23713
+ this._expect(TOKEN.lbrace);
23714
+ const block = this._parseBlock();
23715
+ this._expect(TOKEN.rbrace);
23716
+ if (this._token.id !== TOKEN.eof) {
23717
+ warn2("PostScript function: unexpected content after closing brace.");
23718
+ }
23719
+ return new PsProgram(block);
23720
+ }
23721
+ _parseBlock() {
23722
+ const instructions = [];
23723
+ while (true) {
23724
+ const tok = this._token;
23725
+ switch (tok.id) {
23726
+ case TOKEN.number:
23727
+ instructions.push(new PsNumber(tok.value));
23728
+ this._advance();
23729
+ break;
23730
+ case TOKEN.lbrace: {
23731
+ this._advance();
23732
+ const thenBlock = this._parseBlock();
23733
+ this._expect(TOKEN.rbrace);
23734
+ if (this._token.id === TOKEN.if) {
23735
+ this._advance();
23736
+ instructions.push(new PsIf(thenBlock));
23737
+ } else if (this._token.id === TOKEN.lbrace) {
23738
+ this._advance();
23739
+ const elseBlock = this._parseBlock();
23740
+ this._expect(TOKEN.rbrace);
23741
+ this._expect(TOKEN.ifelse);
23742
+ instructions.push(new PsIfElse(thenBlock, elseBlock));
23743
+ } else {
23744
+ throw new FormatError(
23745
+ "PostScript function: a procedure block must be followed by 'if' or '{\u2026} ifelse'."
23746
+ );
23747
+ }
23748
+ break;
23749
+ }
23750
+ case TOKEN.rbrace:
23751
+ case TOKEN.eof:
23752
+ return new PsBlock(instructions);
23753
+ case TOKEN.if:
23754
+ case TOKEN.ifelse:
23755
+ throw new FormatError(
23756
+ `PostScript function: unexpected '${tok.value}' operator.`
23757
+ );
23758
+ default:
23759
+ if (_Parser._isRegularOperator(tok.id)) {
23760
+ instructions.push(new PsOperator(tok.id));
23761
+ this._advance();
23762
+ break;
23763
+ }
23764
+ throw new FormatError(
23765
+ `PostScript function: unexpected token id ${tok.id}.`
23766
+ );
23767
+ }
23768
+ }
23769
+ }
23770
+ };
23771
+ function parsePostScriptFunction(source) {
23772
+ return new Parser(new Lexer(source)).parse();
23773
+ }
23774
+ function _nodesEqual(a, b) {
23775
+ if (a === b) {
23776
+ return true;
23777
+ }
23778
+ if (a.type !== b.type) {
23779
+ return false;
23780
+ }
23781
+ switch (a.type) {
23782
+ case PS_NODE.arg:
23783
+ return a.index === b.index;
23784
+ case PS_NODE.const:
23785
+ return a.value === b.value;
23786
+ case PS_NODE.unary:
23787
+ return a.op === b.op && _nodesEqual(a.operand, b.operand);
23788
+ case PS_NODE.binary:
23789
+ return a.op === b.op && _nodesEqual(a.first, b.first) && _nodesEqual(a.second, b.second);
23790
+ case PS_NODE.ternary:
23791
+ return _nodesEqual(a.cond, b.cond) && _nodesEqual(a.then, b.then) && _nodesEqual(a.otherwise, b.otherwise);
23792
+ default:
23793
+ return false;
23794
+ }
23795
+ }
23796
+ function _evalBinaryConst(op, a, b) {
23797
+ switch (op) {
23798
+ case TOKEN.add:
23799
+ return a + b;
23800
+ case TOKEN.sub:
23801
+ return a - b;
23802
+ case TOKEN.mul:
23803
+ return a * b;
23804
+ case TOKEN.div:
23805
+ return b !== 0 ? a / b : 0;
23806
+ // div by zero → 0
23807
+ case TOKEN.idiv:
23808
+ return b !== 0 ? Math.trunc(a / b) : 0;
23809
+ // div by zero → 0
23810
+ case TOKEN.mod:
23811
+ return b !== 0 ? a - Math.trunc(a / b) * b : 0;
23812
+ // div by zero → 0
23813
+ case TOKEN.exp: {
23814
+ const r = a ** b;
23815
+ return Number.isFinite(r) ? r : void 0;
23816
+ }
23817
+ case TOKEN.atan: {
23818
+ let deg = Math.atan2(a, b) * (180 / Math.PI);
23819
+ if (deg < 0) {
23820
+ deg += 360;
23821
+ }
23822
+ return deg;
23823
+ }
23824
+ case TOKEN.eq:
23825
+ return a === b;
23826
+ case TOKEN.ne:
23827
+ return a !== b;
23828
+ case TOKEN.gt:
23829
+ return a > b;
23830
+ case TOKEN.ge:
23831
+ return a >= b;
23832
+ case TOKEN.lt:
23833
+ return a < b;
23834
+ case TOKEN.le:
23835
+ return a <= b;
23836
+ case TOKEN.and:
23837
+ return typeof a === "boolean" ? a && b : a & b | 0;
23838
+ case TOKEN.or:
23839
+ return typeof a === "boolean" ? a || b : a | b | 0;
23840
+ case TOKEN.xor:
23841
+ return typeof a === "boolean" ? a !== b : a ^ b | 0;
23842
+ case TOKEN.bitshift:
23843
+ return b >= 0 ? a << b | 0 : a >> -b | 0;
23844
+ case TOKEN.min:
23845
+ return Math.min(a, b);
23846
+ case TOKEN.max:
23847
+ return Math.max(a, b);
23848
+ default:
23849
+ return void 0;
23850
+ }
23851
+ }
23852
+ function _evalUnaryConst(op, v) {
23853
+ switch (op) {
23854
+ case TOKEN.abs:
23855
+ return Math.abs(v);
23856
+ case TOKEN.neg:
23857
+ return -v;
23858
+ case TOKEN.ceiling:
23859
+ return Math.ceil(v);
23860
+ case TOKEN.floor:
23861
+ return Math.floor(v);
23862
+ case TOKEN.round:
23863
+ return Math.round(v);
23864
+ case TOKEN.truncate:
23865
+ return Math.trunc(v);
23866
+ case TOKEN.sqrt: {
23867
+ const r = Math.sqrt(v);
23868
+ return Number.isFinite(r) ? r : void 0;
23869
+ }
23870
+ case TOKEN.sin:
23871
+ return Math.sin(v % 360 * Math.PI / 180);
23872
+ case TOKEN.cos:
23873
+ return Math.cos(v % 360 * Math.PI / 180);
23874
+ case TOKEN.ln: {
23875
+ const r = Math.log(v);
23876
+ return Number.isFinite(r) ? r : void 0;
23877
+ }
23878
+ case TOKEN.log: {
23879
+ const r = Math.log10(v);
23880
+ return Number.isFinite(r) ? r : void 0;
23881
+ }
23882
+ case TOKEN.cvi:
23883
+ return Math.trunc(v);
23884
+ case TOKEN.cvr:
23885
+ return v;
23886
+ case TOKEN.not:
23887
+ return typeof v === "boolean" ? !v : ~v;
23888
+ default:
23889
+ return void 0;
23890
+ }
23891
+ }
23892
+ var MAX_STACK_SIZE = 100;
23893
+ function _unaryValueType(op, operandType) {
23894
+ return op === TOKEN.not ? operandType : PS_VALUE_TYPE.numeric;
23895
+ }
23896
+ function _binaryValueType(op, firstType, secondType) {
23897
+ switch (op) {
23898
+ // Comparison operators always produce a boolean.
23899
+ case TOKEN.eq:
23900
+ case TOKEN.ne:
23901
+ case TOKEN.gt:
23902
+ case TOKEN.ge:
23903
+ case TOKEN.lt:
23904
+ case TOKEN.le:
23905
+ return PS_VALUE_TYPE.boolean;
23906
+ // and / or / xor preserve the type when both operands are the same known
23907
+ // type (both boolean or both numeric); otherwise the type is unknown.
23908
+ case TOKEN.and:
23909
+ case TOKEN.or:
23910
+ case TOKEN.xor:
23911
+ return firstType === secondType && firstType !== PS_VALUE_TYPE.unknown ? firstType : PS_VALUE_TYPE.unknown;
23912
+ // All arithmetic / bitshift operators produce a numeric result.
23913
+ default:
23914
+ return PS_VALUE_TYPE.numeric;
23915
+ }
23916
+ }
23917
+ var PSStackToTree = class _PSStackToTree {
23918
+ static #binaryOps = null;
23919
+ static #unaryOps = null;
23920
+ static #idempotentUnary = null;
23921
+ static #negatedComparison = null;
23922
+ static #init() {
23923
+ this.#binaryOps = /* @__PURE__ */ new Set([
23924
+ TOKEN.add,
23925
+ TOKEN.sub,
23926
+ TOKEN.mul,
23927
+ TOKEN.div,
23928
+ TOKEN.idiv,
23929
+ TOKEN.mod,
23930
+ TOKEN.exp,
23931
+ TOKEN.atan,
23932
+ TOKEN.eq,
23933
+ TOKEN.ne,
23934
+ TOKEN.gt,
23935
+ TOKEN.ge,
23936
+ TOKEN.lt,
23937
+ TOKEN.le,
23938
+ TOKEN.and,
23939
+ TOKEN.or,
23940
+ TOKEN.xor,
23941
+ TOKEN.bitshift
23942
+ ]);
23943
+ this.#unaryOps = /* @__PURE__ */ new Set([
23944
+ TOKEN.abs,
23945
+ TOKEN.neg,
23946
+ TOKEN.ceiling,
23947
+ TOKEN.floor,
23948
+ TOKEN.round,
23949
+ TOKEN.truncate,
23950
+ TOKEN.sqrt,
23951
+ TOKEN.sin,
23952
+ TOKEN.cos,
23953
+ TOKEN.ln,
23954
+ TOKEN.log,
23955
+ TOKEN.cvi,
23956
+ TOKEN.cvr,
23957
+ TOKEN.not
23958
+ ]);
23959
+ this.#idempotentUnary = /* @__PURE__ */ new Set([
23960
+ TOKEN.abs,
23961
+ TOKEN.ceiling,
23962
+ TOKEN.cvi,
23963
+ TOKEN.cvr,
23964
+ TOKEN.floor,
23965
+ TOKEN.round,
23966
+ TOKEN.truncate
23967
+ ]);
23968
+ this.#negatedComparison = /* @__PURE__ */ new Map([
23969
+ [TOKEN.eq, TOKEN.ne],
23970
+ [TOKEN.ne, TOKEN.eq],
23971
+ [TOKEN.lt, TOKEN.ge],
23972
+ [TOKEN.le, TOKEN.gt],
23973
+ [TOKEN.gt, TOKEN.le],
23974
+ [TOKEN.ge, TOKEN.lt]
23975
+ ]);
23976
+ }
23977
+ /**
23978
+ * @param {PsProgram} program
23979
+ * @param {number} numInputs — number of domain values placed on the stack
23980
+ * before the program runs (i.e. the length of the domain array / 2).
23981
+ * @returns {Array<PsNode>} — one tree node per output value.
23982
+ */
23983
+ evaluate(program, numInputs) {
23984
+ if (!_PSStackToTree.#binaryOps) {
23985
+ _PSStackToTree.#init();
23986
+ }
23987
+ this._failed = false;
23988
+ if (numInputs > MAX_STACK_SIZE) {
23989
+ return null;
23990
+ }
23991
+ const stack = [];
23992
+ for (let i = 0; i < numInputs; i++) {
23993
+ stack.push(new PsArgNode(i));
23994
+ }
23995
+ this._evalBlock(program.body, stack);
23996
+ if (this._failed) {
23997
+ return null;
23998
+ }
23999
+ _PSStackToTree.#markShared(stack);
24000
+ return stack;
24001
+ }
24002
+ // Set node.shared / sharedCount on non-atomic nodes referenced more than
24003
+ // once. arg/const are excluded — they are cheap to re-emit inline.
24004
+ static #markShared(outputs) {
24005
+ const refCount = /* @__PURE__ */ new Map();
24006
+ const visit = (node) => {
24007
+ if (!node || node.type === PS_NODE.arg || node.type === PS_NODE.const) {
24008
+ return;
24009
+ }
24010
+ const prev = refCount.get(node) ?? 0;
24011
+ refCount.set(node, prev + 1);
24012
+ if (prev > 0) {
24013
+ return;
24014
+ }
24015
+ switch (node.type) {
24016
+ case PS_NODE.unary:
24017
+ visit(node.operand);
24018
+ break;
24019
+ case PS_NODE.binary:
24020
+ visit(node.first);
24021
+ visit(node.second);
24022
+ break;
24023
+ case PS_NODE.ternary:
24024
+ visit(node.cond);
24025
+ visit(node.then);
24026
+ visit(node.otherwise);
24027
+ break;
24028
+ }
24029
+ };
24030
+ for (const output of outputs) {
24031
+ visit(output);
24032
+ }
24033
+ for (const [node, count] of refCount) {
24034
+ if (count > 1) {
24035
+ node.shared = true;
24036
+ node.sharedCount = count;
24037
+ }
24038
+ }
24039
+ }
24040
+ _evalBlock(block, stack) {
24041
+ this._evalBlockFrom(block.instructions, 0, stack);
24042
+ }
24043
+ /**
24044
+ * Core evaluation loop. Processes `instructions[startIdx…]` in order,
24045
+ * mutating `stack` as each instruction executes.
24046
+ *
24047
+ * When a `{ body } if` instruction grows the stack (the PostScript "early
24048
+ * exit / guard" idiom), the remaining instructions in the current array are
24049
+ * evaluated on **both** the true-branch stack and the false-branch stack,
24050
+ * then the two results are merged into PsTernaryNodes. This handles
24051
+ * patterns like:
24052
+ *
24053
+ * cond { pop R G B sentinel } if
24054
+ * … more guards …
24055
+ * sentinel 0 gt { defaultR defaultG defaultB } if
24056
+ */
24057
+ _evalBlockFrom(instructions, startIdx, stack) {
24058
+ for (let idx = startIdx; idx < instructions.length; idx++) {
24059
+ if (this._failed) {
24060
+ break;
24061
+ }
24062
+ const instr = instructions[idx];
24063
+ switch (instr.type) {
24064
+ case PS_NODE.number:
24065
+ stack.push(new PsConstNode(instr.value));
24066
+ if (stack.length > MAX_STACK_SIZE) {
24067
+ this._failed = true;
24068
+ }
24069
+ break;
24070
+ case PS_NODE.operator:
24071
+ this._evalOp(instr.op, stack);
24072
+ break;
24073
+ case PS_NODE.if: {
24074
+ if (stack.length < 1) {
24075
+ this._failed = true;
24076
+ break;
24077
+ }
24078
+ const cond = stack.pop();
24079
+ const saved = stack.slice();
24080
+ this._evalBlock(instr.then, stack);
24081
+ if (this._failed) {
24082
+ break;
24083
+ }
24084
+ if (stack.length === saved.length) {
24085
+ for (let i = 0; i < stack.length; i++) {
24086
+ if (stack[i] !== saved[i]) {
24087
+ stack[i] = this._makeTernary(cond, stack[i], saved[i]);
24088
+ }
24089
+ }
24090
+ } else if (stack.length > saved.length) {
24091
+ if (cond.type === PS_NODE.const) {
24092
+ if (!cond.value) {
24093
+ stack.length = 0;
24094
+ stack.push(...saved);
24095
+ }
24096
+ break;
24097
+ }
24098
+ const trueStack = stack.slice();
24099
+ this._evalBlockFrom(instructions, idx + 1, trueStack);
24100
+ if (this._failed) {
24101
+ break;
24102
+ }
24103
+ const falseStack = saved;
24104
+ this._evalBlockFrom(instructions, idx + 1, falseStack);
24105
+ if (this._failed) {
24106
+ break;
24107
+ }
24108
+ if (trueStack.length !== falseStack.length) {
24109
+ const zero2 = new PsConstNode(0);
24110
+ while (trueStack.length < falseStack.length) {
24111
+ trueStack.push(zero2);
24112
+ }
24113
+ while (falseStack.length < trueStack.length) {
24114
+ falseStack.push(zero2);
24115
+ }
24116
+ }
24117
+ stack.length = 0;
24118
+ for (let i = 0; i < trueStack.length; i++) {
24119
+ stack.push(this._makeTernary(cond, trueStack[i], falseStack[i]));
24120
+ }
24121
+ return;
24122
+ } else {
24123
+ this._failed = true;
24124
+ }
24125
+ break;
24126
+ }
24127
+ case PS_NODE.ifelse: {
24128
+ if (stack.length < 1) {
24129
+ this._failed = true;
24130
+ break;
24131
+ }
24132
+ const cond = stack.pop();
24133
+ const snapshot = stack.slice();
24134
+ const thenStack = snapshot.slice();
24135
+ this._evalBlock(instr.then, thenStack);
24136
+ if (this._failed) {
24137
+ break;
24138
+ }
24139
+ const elseStack = snapshot.slice();
24140
+ this._evalBlock(instr.otherwise, elseStack);
24141
+ if (this._failed) {
24142
+ break;
24143
+ }
24144
+ if (thenStack.length !== elseStack.length) {
24145
+ const zero2 = new PsConstNode(0);
24146
+ while (thenStack.length < elseStack.length) {
24147
+ thenStack.push(zero2);
24148
+ }
24149
+ while (elseStack.length < thenStack.length) {
24150
+ elseStack.push(zero2);
24151
+ }
24152
+ }
24153
+ stack.length = 0;
24154
+ for (let i = 0; i < thenStack.length; i++) {
24155
+ stack.push(this._makeTernary(cond, thenStack[i], elseStack[i]));
24156
+ }
24157
+ break;
24158
+ }
24159
+ }
24160
+ }
24161
+ }
24162
+ _evalOp(op, stack) {
24163
+ if (_PSStackToTree.#binaryOps.has(op)) {
24164
+ if (stack.length < 2) {
24165
+ this._failed = true;
24166
+ return;
24167
+ }
24168
+ const first = stack.pop();
24169
+ const second = stack.pop();
24170
+ stack.push(this._makeBinary(op, first, second));
24171
+ return;
24172
+ }
24173
+ if (_PSStackToTree.#unaryOps.has(op)) {
24174
+ if (stack.length < 1) {
24175
+ this._failed = true;
24176
+ return;
24177
+ }
24178
+ stack.push(this._makeUnary(op, stack.pop()));
24179
+ return;
24180
+ }
24181
+ switch (op) {
24182
+ case TOKEN.true:
24183
+ stack.push(new PsConstNode(true));
24184
+ if (stack.length > MAX_STACK_SIZE) {
24185
+ this._failed = true;
24186
+ }
24187
+ break;
24188
+ case TOKEN.false:
24189
+ stack.push(new PsConstNode(false));
24190
+ if (stack.length > MAX_STACK_SIZE) {
24191
+ this._failed = true;
24192
+ }
24193
+ break;
24194
+ case TOKEN.dup:
24195
+ if (stack.length < 1) {
24196
+ this._failed = true;
24197
+ break;
24198
+ }
24199
+ stack.push(stack.at(-1));
24200
+ if (stack.length > MAX_STACK_SIZE) {
24201
+ this._failed = true;
24202
+ }
24203
+ break;
24204
+ case TOKEN.exch: {
24205
+ if (stack.length < 2) {
24206
+ this._failed = true;
24207
+ break;
24208
+ }
24209
+ const a = stack.pop();
24210
+ const b = stack.pop();
24211
+ stack.push(a, b);
24212
+ break;
24213
+ }
24214
+ case TOKEN.pop:
24215
+ if (stack.length < 1) {
24216
+ this._failed = true;
24217
+ break;
24218
+ }
24219
+ stack.pop();
24220
+ break;
24221
+ case TOKEN.copy: {
24222
+ if (stack.length < 1) {
24223
+ this._failed = true;
24224
+ break;
24225
+ }
24226
+ const nNode = stack.pop();
24227
+ if (nNode.type === PS_NODE.const) {
24228
+ const n = nNode.value | 0;
24229
+ if (n === 0) {
24230
+ } else if (n < 0 || n > stack.length) {
24231
+ this._failed = true;
24232
+ } else {
24233
+ stack.push(...stack.slice(-n));
24234
+ if (stack.length > MAX_STACK_SIZE) {
24235
+ this._failed = true;
24236
+ }
24237
+ }
24238
+ } else {
24239
+ this._failed = true;
24240
+ }
24241
+ break;
24242
+ }
24243
+ case TOKEN.index: {
24244
+ if (stack.length < 1) {
24245
+ this._failed = true;
24246
+ break;
24247
+ }
24248
+ const nNode = stack.pop();
24249
+ if (nNode.type === PS_NODE.const) {
24250
+ const n = nNode.value | 0;
24251
+ if (n < 0 || n >= stack.length) {
24252
+ this._failed = true;
24253
+ } else {
24254
+ stack.push(stack.at(-n - 1));
24255
+ }
24256
+ } else {
24257
+ this._failed = true;
24258
+ }
24259
+ break;
24260
+ }
24261
+ case TOKEN.roll: {
24262
+ if (stack.length < 2) {
24263
+ this._failed = true;
24264
+ break;
24265
+ }
24266
+ const jNode = stack.pop();
24267
+ const nNode = stack.pop();
24268
+ if (nNode.type === PS_NODE.const && jNode.type === PS_NODE.const) {
24269
+ const n = nNode.value | 0;
24270
+ if (n === 0) {
24271
+ } else if (n < 0 || n > stack.length) {
24272
+ this._failed = true;
24273
+ } else {
24274
+ const j = ((jNode.value | 0) % n + n) % n;
24275
+ if (j > 0) {
24276
+ const slice = stack.splice(-n, n);
24277
+ stack.push(...slice.slice(n - j), ...slice.slice(0, n - j));
24278
+ }
24279
+ }
24280
+ } else {
24281
+ this._failed = true;
24282
+ }
24283
+ break;
24284
+ }
24285
+ default:
24286
+ this._failed = true;
24287
+ break;
24288
+ }
24289
+ }
24290
+ /**
24291
+ * Create a binary tree node, applying optimizations eagerly:
24292
+ *
24293
+ * 1. Constant folding — both operands are PsConstNode → fold to PsConstNode.
24294
+ * 2. Reflexive simplifications — x−x→0, x xor x→0, x eq x→true, etc.
24295
+ * 3. Algebraic simplifications with one known operand — identity elements
24296
+ * (x+0→x, x*1→x, …), absorbing elements (x*0→0, x and false→false, …),
24297
+ * and strength reductions (x*-1→neg(x), x^0.5→sqrt(x), x^2→x*x, …).
24298
+ *
24299
+ * Recall: `first` was on top of the stack (right operand for non-commutative
24300
+ * ops), `second` was below (left operand). So `a b sub` → second=a, first=b
24301
+ * → a − b.
24302
+ */
24303
+ _makeBinary(op, first, second) {
24304
+ if (first.type === PS_NODE.const && second.type === PS_NODE.const) {
24305
+ const v = _evalBinaryConst(op, second.value, first.value);
24306
+ if (v !== void 0) {
24307
+ return new PsConstNode(v);
24308
+ }
24309
+ }
24310
+ if (_nodesEqual(first, second)) {
24311
+ switch (op) {
24312
+ case TOKEN.sub:
24313
+ return new PsConstNode(0);
24314
+ // x − x → 0
24315
+ case TOKEN.xor:
24316
+ return new PsConstNode(
24317
+ /* eslint-disable unicorn/prefer-logical-operator-over-ternary */
24318
+ first.valueType === PS_VALUE_TYPE.boolean ? false : 0
24319
+ /* eslint-enable unicorn/prefer-logical-operator-over-ternary */
24320
+ );
24321
+ // TOKEN.mod, TOKEN.div, TOKEN.idiv are NOT simplified here:
24322
+ // x op x is undefined when x = 0, so we cannot fold without knowing
24323
+ // that x is non-zero.
24324
+ case TOKEN.and:
24325
+ case TOKEN.or:
24326
+ return first;
24327
+ // x and x → x; x or x → x
24328
+ case TOKEN.min:
24329
+ case TOKEN.max:
24330
+ return first;
24331
+ // min(x,x) → x; max(x,x) → x
24332
+ case TOKEN.eq:
24333
+ case TOKEN.ge:
24334
+ case TOKEN.le:
24335
+ return new PsConstNode(true);
24336
+ case TOKEN.ne:
24337
+ case TOKEN.gt:
24338
+ case TOKEN.lt:
24339
+ return new PsConstNode(false);
24340
+ }
24341
+ }
24342
+ if (first.type === PS_NODE.const) {
24343
+ const b = first.value;
24344
+ switch (op) {
24345
+ case TOKEN.add:
24346
+ if (b === 0) {
24347
+ return second;
24348
+ }
24349
+ break;
24350
+ case TOKEN.sub:
24351
+ if (b === 0) {
24352
+ return second;
24353
+ }
24354
+ break;
24355
+ case TOKEN.mul:
24356
+ if (b === 1) {
24357
+ return second;
24358
+ }
24359
+ if (b === 0) {
24360
+ return first;
24361
+ }
24362
+ if (b === -1) {
24363
+ return this._makeUnary(TOKEN.neg, second);
24364
+ }
24365
+ break;
24366
+ case TOKEN.div:
24367
+ if (b !== 0) {
24368
+ return this._makeBinary(TOKEN.mul, new PsConstNode(1 / b), second);
24369
+ }
24370
+ break;
24371
+ case TOKEN.idiv:
24372
+ if (b === 1) {
24373
+ return second;
24374
+ }
24375
+ break;
24376
+ case TOKEN.exp:
24377
+ if (b === 1) {
24378
+ return second;
24379
+ }
24380
+ if (b === -1) {
24381
+ return this._makeBinary(TOKEN.div, second, new PsConstNode(1));
24382
+ }
24383
+ if (b === 0.5) {
24384
+ return this._makeUnary(TOKEN.sqrt, second);
24385
+ }
24386
+ if (b === 0.25) {
24387
+ const sqrtOnce = this._makeUnary(TOKEN.sqrt, second);
24388
+ return this._makeUnary(TOKEN.sqrt, sqrtOnce);
24389
+ }
24390
+ if (b === 2) {
24391
+ return this._makeBinary(TOKEN.mul, second, second);
24392
+ }
24393
+ if (b === 3) {
24394
+ return this._makeBinary(
24395
+ TOKEN.mul,
24396
+ this._makeBinary(TOKEN.mul, second, second),
24397
+ second
24398
+ );
24399
+ }
24400
+ if (b === 4) {
24401
+ const square = this._makeBinary(TOKEN.mul, second, second);
24402
+ return this._makeBinary(TOKEN.mul, square, square);
24403
+ }
24404
+ if (b === 0) {
24405
+ return new PsConstNode(1);
24406
+ }
24407
+ break;
24408
+ case TOKEN.and:
24409
+ if (b === true) {
24410
+ return second;
24411
+ }
24412
+ if (b === false) {
24413
+ return first;
24414
+ }
24415
+ break;
24416
+ case TOKEN.or:
24417
+ if (b === false) {
24418
+ return second;
24419
+ }
24420
+ if (b === true) {
24421
+ return first;
24422
+ }
24423
+ break;
24424
+ case TOKEN.min:
24425
+ if (second.type === PS_NODE.binary && second.op === TOKEN.max && second.first.type === PS_NODE.const && second.first.value >= b) {
24426
+ return first;
24427
+ }
24428
+ break;
24429
+ case TOKEN.max:
24430
+ if (second.type === PS_NODE.binary && second.op === TOKEN.min && second.first.type === PS_NODE.const && second.first.value <= b) {
24431
+ return first;
24432
+ }
24433
+ break;
24434
+ }
24435
+ }
24436
+ if (second.type === PS_NODE.const) {
24437
+ const a = second.value;
24438
+ switch (op) {
24439
+ case TOKEN.add:
24440
+ if (a === 0) {
24441
+ return first;
24442
+ }
24443
+ break;
24444
+ case TOKEN.sub:
24445
+ if (a === 0) {
24446
+ return this._makeUnary(TOKEN.neg, first);
24447
+ }
24448
+ break;
24449
+ case TOKEN.mul:
24450
+ if (a === 1) {
24451
+ return first;
24452
+ }
24453
+ if (a === 0) {
24454
+ return second;
24455
+ }
24456
+ if (a === -1) {
24457
+ return this._makeUnary(TOKEN.neg, first);
24458
+ }
24459
+ break;
24460
+ case TOKEN.and:
24461
+ if (a === true) {
24462
+ return first;
24463
+ }
24464
+ if (a === false) {
24465
+ return second;
24466
+ }
24467
+ break;
24468
+ case TOKEN.or:
24469
+ if (a === false) {
24470
+ return first;
24471
+ }
24472
+ if (a === true) {
24473
+ return second;
24474
+ }
24475
+ break;
24476
+ }
24477
+ }
24478
+ return new PsBinaryNode(
24479
+ op,
24480
+ first,
24481
+ second,
24482
+ _binaryValueType(op, first.valueType, second.valueType)
24483
+ );
24484
+ }
24485
+ /**
24486
+ * Create a unary tree node, applying optimizations eagerly:
24487
+ *
24488
+ * 1. Constant folding.
24489
+ * 2. not(comparison) → negated comparison: not(a eq b) → a ne b, etc.
24490
+ * 3. neg(a − b) → b − a.
24491
+ * 4. Double-negation: neg(neg(x)) → x, not(not(x)) → x.
24492
+ * 5. abs(neg(x)) → abs(x).
24493
+ * 6. Idempotent: f(f(x)) → f(x) for abs, ceiling, floor, round, etc.
24494
+ */
24495
+ _makeUnary(op, operand) {
24496
+ if (operand.type === PS_NODE.const) {
24497
+ const v = _evalUnaryConst(op, operand.value);
24498
+ if (v !== void 0) {
24499
+ return new PsConstNode(v);
24500
+ }
24501
+ }
24502
+ if (op === TOKEN.not && operand.type === PS_NODE.binary) {
24503
+ const negated = _PSStackToTree.#negatedComparison.get(operand.op);
24504
+ if (negated !== void 0) {
24505
+ return new PsBinaryNode(
24506
+ negated,
24507
+ operand.first,
24508
+ operand.second,
24509
+ PS_VALUE_TYPE.boolean
24510
+ );
24511
+ }
24512
+ }
24513
+ if (op === TOKEN.neg && operand.type === PS_NODE.binary && operand.op === TOKEN.sub) {
24514
+ return this._makeBinary(TOKEN.sub, operand.second, operand.first);
24515
+ }
24516
+ if (operand.type === PS_NODE.unary) {
24517
+ if (op === TOKEN.neg && operand.op === TOKEN.neg || op === TOKEN.not && operand.op === TOKEN.not) {
24518
+ return operand.operand;
24519
+ }
24520
+ if (op === TOKEN.abs && operand.op === TOKEN.neg) {
24521
+ return this._makeUnary(TOKEN.abs, operand.operand);
24522
+ }
24523
+ if (_PSStackToTree.#idempotentUnary.has(op) && op === operand.op) {
24524
+ return operand;
24525
+ }
24526
+ }
24527
+ return new PsUnaryNode(op, operand, _unaryValueType(op, operand.valueType));
24528
+ }
24529
+ /**
24530
+ * Create a ternary node, applying optimizations eagerly:
24531
+ *
24532
+ * 1. Constant condition — fold to the live branch.
24533
+ * 2. Identical branches — the condition is irrelevant, return either branch.
24534
+ * 3. Boolean branch constants — `cond ? true : false` → cond,
24535
+ * `cond ? false : true` → not(cond).
24536
+ * 4. Ternary → branchless min/max when the condition compares two numeric
24537
+ * expressions that are also the two branches.
24538
+ */
24539
+ _makeTernary(cond, then, otherwise) {
24540
+ if (cond.type === PS_NODE.const) {
24541
+ return cond.value ? then : otherwise;
24542
+ }
24543
+ if (_nodesEqual(then, otherwise)) {
24544
+ return then;
24545
+ }
24546
+ if (then.type === PS_NODE.const && otherwise.type === PS_NODE.const) {
24547
+ if (then.value === true && otherwise.value === false) {
24548
+ return cond;
24549
+ }
24550
+ if (then.value === false && otherwise.value === true) {
24551
+ return this._makeUnary(TOKEN.not, cond);
24552
+ }
24553
+ }
24554
+ if (cond.type === PS_NODE.binary) {
24555
+ const { op: cop, first: cf, second: cs } = cond;
24556
+ if (cop === TOKEN.gt || cop === TOKEN.ge) {
24557
+ if (_nodesEqual(then, cf) && _nodesEqual(otherwise, cs)) {
24558
+ return this._makeBinary(TOKEN.min, cf, cs);
24559
+ }
24560
+ if (_nodesEqual(then, cs) && _nodesEqual(otherwise, cf)) {
24561
+ return this._makeBinary(TOKEN.max, cf, cs);
24562
+ }
24563
+ } else if (cop === TOKEN.lt || cop === TOKEN.le) {
24564
+ if (_nodesEqual(then, cf) && _nodesEqual(otherwise, cs)) {
24565
+ return this._makeBinary(TOKEN.max, cf, cs);
24566
+ }
24567
+ if (_nodesEqual(then, cs) && _nodesEqual(otherwise, cf)) {
24568
+ return this._makeBinary(TOKEN.min, cf, cs);
24569
+ }
24570
+ }
24571
+ }
24572
+ return new PsTernaryNode(
24573
+ cond,
24574
+ then,
24575
+ otherwise,
24576
+ then.valueType === otherwise.valueType ? then.valueType : PS_VALUE_TYPE.unknown
24577
+ );
24578
+ }
24579
+ };
24580
+ var OP = {
24581
+ ARG: 0,
24582
+ // [ARG, idx]
24583
+ CONST: 1,
24584
+ // [CONST, val]
24585
+ STORE: 2,
24586
+ // [STORE, slot, min, max] clamp(pop()) → mem[slot]
24587
+ IF: 3,
24588
+ // [IF, target] jump when top-of-stack === 0
24589
+ JUMP: 4,
24590
+ // [JUMP, target] unconditional
24591
+ ABS: 5,
24592
+ NEG: 6,
24593
+ CEIL: 7,
24594
+ FLOOR: 8,
24595
+ ROUND: 9,
24596
+ // floor(x + 0.5)
24597
+ TRUNC: 10,
24598
+ NOT_B: 11,
24599
+ // boolean NOT
24600
+ NOT_N: 12,
24601
+ // bitwise NOT
24602
+ SQRT: 13,
24603
+ SIN: 14,
24604
+ // degrees in/out
24605
+ COS: 15,
24606
+ LN: 16,
24607
+ LOG10: 17,
24608
+ CVI: 18,
24609
+ SHIFT: 19,
24610
+ // [SHIFT, amount] +ve = left, −ve = right
24611
+ // Binary ops: second below, first on top; result = second OP first.
24612
+ ADD: 20,
24613
+ SUB: 21,
24614
+ MUL: 22,
24615
+ DIV: 23,
24616
+ // 0 when divisor is 0
24617
+ IDIV: 24,
24618
+ // 0 when divisor is 0
24619
+ MOD: 25,
24620
+ // 0 when divisor is 0
24621
+ POW: 26,
24622
+ EQ: 27,
24623
+ NE: 28,
24624
+ GT: 29,
24625
+ GE: 30,
24626
+ LT: 31,
24627
+ LE: 32,
24628
+ AND: 33,
24629
+ OR: 34,
24630
+ XOR: 35,
24631
+ ATAN: 36,
24632
+ // atan2(second, first) → degrees [0, 360)
24633
+ MIN: 37,
24634
+ MAX: 38,
24635
+ TEE_TMP: 39,
24636
+ // [TEE_TMP, slot] peek top of stack → tmp[slot], leave on stack
24637
+ LOAD_TMP: 40
24638
+ // [LOAD_TMP, slot] push tmp[slot]
24639
+ };
24640
+ var _DEG_TO_RAD = Math.PI / 180;
24641
+ var _RAD_TO_DEG = 180 / Math.PI;
24642
+ var PsJsCompiler = class {
24643
+ // Safe because JS is single-threaded.
24644
+ static #stack = new Float64Array(64);
24645
+ static #tmp = new Float64Array(64);
24646
+ constructor(domain, range) {
24647
+ this.nIn = domain.length >> 1;
24648
+ this.nOut = range.length >> 1;
24649
+ this.range = range;
24650
+ this.ir = [];
24651
+ this._tmpMap = /* @__PURE__ */ new Map();
24652
+ this._nextTmp = 0;
24653
+ }
24654
+ _compileNode(node) {
24655
+ if (node.shared) {
24656
+ const cached = this._tmpMap.get(node);
24657
+ if (cached !== void 0) {
24658
+ this.ir.push(OP.LOAD_TMP, cached);
24659
+ return true;
24660
+ }
24661
+ if (!this._compileNodeImpl(node)) {
24662
+ return false;
24663
+ }
24664
+ const slot = this._nextTmp++;
24665
+ this._tmpMap.set(node, slot);
24666
+ this.ir.push(OP.TEE_TMP, slot);
24667
+ return true;
24668
+ }
24669
+ return this._compileNodeImpl(node);
24670
+ }
24671
+ _compileNodeImpl(node) {
24672
+ switch (node.type) {
24673
+ case PS_NODE.arg:
24674
+ this.ir.push(OP.ARG, node.index);
24675
+ return true;
24676
+ case PS_NODE.const: {
24677
+ const v = node.value;
24678
+ this.ir.push(OP.CONST, typeof v === "boolean" ? Number(v) : v);
24679
+ return true;
24680
+ }
24681
+ case PS_NODE.unary:
24682
+ return this._compileUnary(node);
24683
+ case PS_NODE.binary:
24684
+ return this._compileBinary(node);
24685
+ case PS_NODE.ternary:
24686
+ return this._compileTernary(node);
24687
+ default:
24688
+ return false;
24689
+ }
24690
+ }
24691
+ _compileUnary(node) {
24692
+ const { op, operand, valueType } = node;
24693
+ if (op === TOKEN.cvr) {
24694
+ return this._compileNode(operand);
24695
+ }
24696
+ if (!this._compileNode(operand)) {
24697
+ return false;
24698
+ }
24699
+ switch (op) {
24700
+ case TOKEN.abs:
24701
+ this.ir.push(OP.ABS);
24702
+ break;
24703
+ case TOKEN.neg:
24704
+ this.ir.push(OP.NEG);
24705
+ break;
24706
+ case TOKEN.ceiling:
24707
+ this.ir.push(OP.CEIL);
24708
+ break;
24709
+ case TOKEN.floor:
24710
+ this.ir.push(OP.FLOOR);
24711
+ break;
24712
+ case TOKEN.round:
24713
+ this.ir.push(OP.ROUND);
24714
+ break;
24715
+ case TOKEN.truncate:
24716
+ this.ir.push(OP.TRUNC);
24717
+ break;
24718
+ case TOKEN.sqrt:
24719
+ this.ir.push(OP.SQRT);
24720
+ break;
24721
+ case TOKEN.sin:
24722
+ this.ir.push(OP.SIN);
24723
+ break;
24724
+ case TOKEN.cos:
24725
+ this.ir.push(OP.COS);
24726
+ break;
24727
+ case TOKEN.ln:
24728
+ this.ir.push(OP.LN);
24729
+ break;
24730
+ case TOKEN.log:
24731
+ this.ir.push(OP.LOG10);
24732
+ break;
24733
+ case TOKEN.cvi:
24734
+ this.ir.push(OP.CVI);
24735
+ break;
24736
+ case TOKEN.not:
24737
+ if (valueType === PS_VALUE_TYPE.boolean) {
24738
+ this.ir.push(OP.NOT_B);
24739
+ } else if (valueType === PS_VALUE_TYPE.numeric) {
24740
+ this.ir.push(OP.NOT_N);
24741
+ } else {
24742
+ return false;
24743
+ }
24744
+ break;
24745
+ default:
24746
+ return false;
24747
+ }
24748
+ return true;
24749
+ }
24750
+ _compileBinary(node) {
24751
+ const { op, first, second } = node;
24752
+ if (op === TOKEN.bitshift) {
24753
+ if (first.type !== PS_NODE.const || !Number.isInteger(first.value) || !this._compileNode(second)) {
24754
+ return false;
24755
+ }
24756
+ this.ir.push(OP.SHIFT, first.value);
24757
+ return true;
24758
+ }
24759
+ if (!this._compileNode(second) || !this._compileNode(first)) {
24760
+ return false;
24761
+ }
24762
+ switch (op) {
24763
+ case TOKEN.add:
24764
+ this.ir.push(OP.ADD);
24765
+ break;
24766
+ case TOKEN.sub:
24767
+ this.ir.push(OP.SUB);
24768
+ break;
24769
+ case TOKEN.mul:
24770
+ this.ir.push(OP.MUL);
24771
+ break;
24772
+ case TOKEN.div:
24773
+ this.ir.push(OP.DIV);
24774
+ break;
24775
+ case TOKEN.idiv:
24776
+ this.ir.push(OP.IDIV);
24777
+ break;
24778
+ case TOKEN.mod:
24779
+ this.ir.push(OP.MOD);
24780
+ break;
24781
+ case TOKEN.exp:
24782
+ this.ir.push(OP.POW);
24783
+ break;
24784
+ case TOKEN.eq:
24785
+ this.ir.push(OP.EQ);
24786
+ break;
24787
+ case TOKEN.ne:
24788
+ this.ir.push(OP.NE);
24789
+ break;
24790
+ case TOKEN.gt:
24791
+ this.ir.push(OP.GT);
24792
+ break;
24793
+ case TOKEN.ge:
24794
+ this.ir.push(OP.GE);
24795
+ break;
24796
+ case TOKEN.lt:
24797
+ this.ir.push(OP.LT);
24798
+ break;
24799
+ case TOKEN.le:
24800
+ this.ir.push(OP.LE);
24801
+ break;
24802
+ case TOKEN.and:
24803
+ this.ir.push(OP.AND);
24804
+ break;
24805
+ case TOKEN.or:
24806
+ this.ir.push(OP.OR);
24807
+ break;
24808
+ case TOKEN.xor:
24809
+ this.ir.push(OP.XOR);
24810
+ break;
24811
+ case TOKEN.atan:
24812
+ this.ir.push(OP.ATAN);
24813
+ break;
24814
+ case TOKEN.min:
24815
+ this.ir.push(OP.MIN);
24816
+ break;
24817
+ case TOKEN.max:
24818
+ this.ir.push(OP.MAX);
24819
+ break;
24820
+ default:
24821
+ return false;
24822
+ }
24823
+ return true;
24824
+ }
24825
+ _compileTernary(node) {
24826
+ if (!this._compileNode(node.cond)) {
24827
+ return false;
24828
+ }
24829
+ this.ir.push(OP.IF, 0);
24830
+ const ifPatch = this.ir.length - 1;
24831
+ if (!this._compileNode(node.then)) {
24832
+ return false;
24833
+ }
24834
+ this.ir.push(OP.JUMP, 0);
24835
+ const jumpPatch = this.ir.length - 1;
24836
+ this.ir[ifPatch] = this.ir.length;
24837
+ if (!this._compileNode(node.otherwise)) {
24838
+ return false;
24839
+ }
24840
+ this.ir[jumpPatch] = this.ir.length;
24841
+ return true;
24842
+ }
24843
+ compile(program) {
24844
+ const outputs = new PSStackToTree().evaluate(program, this.nIn);
24845
+ if (!outputs || outputs.length < this.nOut) {
24846
+ return null;
24847
+ }
24848
+ for (let i = 0; i < this.nOut; i++) {
24849
+ if (!this._compileNode(outputs[i])) {
24850
+ return null;
24851
+ }
24852
+ const min = this.range[i * 2];
24853
+ const max = this.range[i * 2 + 1];
24854
+ this.ir.push(OP.STORE, i, min, max);
24855
+ }
24856
+ return new Float64Array(this.ir);
24857
+ }
24858
+ static execute(ir, src, srcOffset, dest, destOffset) {
24859
+ let ip = 0, sp = 0;
24860
+ const n = ir.length;
24861
+ const stack = this.#stack;
24862
+ const tmp = this.#tmp;
24863
+ while (ip < n) {
24864
+ switch (ir[ip++] | 0) {
24865
+ case OP.ARG:
24866
+ stack[sp++] = src[srcOffset + (ir[ip++] | 0)];
24867
+ break;
24868
+ case OP.CONST:
24869
+ stack[sp++] = ir[ip++];
24870
+ break;
24871
+ case OP.STORE: {
24872
+ const slot = ir[ip++] | 0;
24873
+ const min = ir[ip++];
24874
+ const max = ir[ip++];
24875
+ dest[destOffset + slot] = MathClamp(stack[--sp], min, max);
24876
+ break;
24877
+ }
24878
+ case OP.IF: {
24879
+ const tgt = ir[ip++];
24880
+ if (stack[--sp] === 0) {
24881
+ ip = tgt;
24882
+ }
24883
+ break;
24884
+ }
24885
+ case OP.JUMP:
24886
+ ip = ir[ip];
24887
+ break;
24888
+ case OP.ABS:
24889
+ stack[sp - 1] = Math.abs(stack[sp - 1]);
24890
+ break;
24891
+ case OP.NEG:
24892
+ stack[sp - 1] = -stack[sp - 1];
24893
+ break;
24894
+ case OP.CEIL:
24895
+ stack[sp - 1] = Math.ceil(stack[sp - 1]);
24896
+ break;
24897
+ case OP.FLOOR:
24898
+ stack[sp - 1] = Math.floor(stack[sp - 1]);
24899
+ break;
24900
+ case OP.ROUND:
24901
+ stack[sp - 1] = Math.floor(stack[sp - 1] + 0.5);
24902
+ break;
24903
+ case OP.TRUNC:
24904
+ stack[sp - 1] = Math.trunc(stack[sp - 1]);
24905
+ break;
24906
+ case OP.NOT_B:
24907
+ stack[sp - 1] = stack[sp - 1] !== 0 ? 0 : 1;
24908
+ break;
24909
+ case OP.NOT_N:
24910
+ stack[sp - 1] = ~(stack[sp - 1] | 0);
24911
+ break;
24912
+ case OP.SQRT:
24913
+ stack[sp - 1] = Math.sqrt(stack[sp - 1]);
24914
+ break;
24915
+ case OP.SIN:
24916
+ stack[sp - 1] = Math.sin(stack[sp - 1] % 360 * _DEG_TO_RAD);
24917
+ break;
24918
+ case OP.COS:
24919
+ stack[sp - 1] = Math.cos(stack[sp - 1] % 360 * _DEG_TO_RAD);
24920
+ break;
24921
+ case OP.LN:
24922
+ stack[sp - 1] = Math.log(stack[sp - 1]);
24923
+ break;
24924
+ case OP.LOG10:
24925
+ stack[sp - 1] = Math.log10(stack[sp - 1]);
24926
+ break;
24927
+ case OP.CVI:
24928
+ stack[sp - 1] = Math.trunc(stack[sp - 1]) | 0;
24929
+ break;
24930
+ case OP.SHIFT: {
24931
+ const amt = ir[ip++];
24932
+ const v = stack[sp - 1] | 0;
24933
+ if (amt > 0) {
24934
+ stack[sp - 1] = v << amt;
24935
+ } else if (amt < 0) {
24936
+ stack[sp - 1] = v >> -amt;
24937
+ } else {
24938
+ stack[sp - 1] = v;
24939
+ }
24940
+ break;
24941
+ }
24942
+ case OP.ADD: {
24943
+ const b = stack[--sp];
24944
+ stack[sp - 1] += b;
24945
+ break;
24946
+ }
24947
+ case OP.SUB: {
24948
+ const b = stack[--sp];
24949
+ stack[sp - 1] -= b;
24950
+ break;
24951
+ }
24952
+ case OP.MUL: {
24953
+ const b = stack[--sp];
24954
+ stack[sp - 1] *= b;
24955
+ break;
24956
+ }
24957
+ case OP.DIV: {
24958
+ const b = stack[--sp];
24959
+ stack[sp - 1] = b !== 0 ? stack[sp - 1] / b : 0;
24960
+ break;
24961
+ }
24962
+ case OP.IDIV: {
24963
+ const b = stack[--sp];
24964
+ stack[sp - 1] = b !== 0 ? Math.trunc(stack[sp - 1] / b) : 0;
24965
+ break;
24966
+ }
24967
+ case OP.MOD: {
24968
+ const b = stack[--sp];
24969
+ stack[sp - 1] = b !== 0 ? stack[sp - 1] % b : 0;
24970
+ break;
24971
+ }
24972
+ case OP.POW: {
24973
+ const b = stack[--sp];
24974
+ stack[sp - 1] **= b;
24975
+ break;
24976
+ }
24977
+ case OP.EQ: {
24978
+ const b = stack[--sp];
24979
+ stack[sp - 1] = stack[sp - 1] === b ? 1 : 0;
24980
+ break;
24981
+ }
24982
+ case OP.NE: {
24983
+ const b = stack[--sp];
24984
+ stack[sp - 1] = stack[sp - 1] !== b ? 1 : 0;
24985
+ break;
24986
+ }
24987
+ case OP.GT: {
24988
+ const b = stack[--sp];
24989
+ stack[sp - 1] = stack[sp - 1] > b ? 1 : 0;
24990
+ break;
24991
+ }
24992
+ case OP.GE: {
24993
+ const b = stack[--sp];
24994
+ stack[sp - 1] = stack[sp - 1] >= b ? 1 : 0;
24995
+ break;
24996
+ }
24997
+ case OP.LT: {
24998
+ const b = stack[--sp];
24999
+ stack[sp - 1] = stack[sp - 1] < b ? 1 : 0;
25000
+ break;
25001
+ }
25002
+ case OP.LE: {
25003
+ const b = stack[--sp];
25004
+ stack[sp - 1] = stack[sp - 1] <= b ? 1 : 0;
25005
+ break;
25006
+ }
25007
+ case OP.AND: {
25008
+ const b = stack[--sp] | 0;
25009
+ stack[sp - 1] = (stack[sp - 1] | 0) & b;
25010
+ break;
25011
+ }
25012
+ case OP.OR: {
25013
+ const b = stack[--sp] | 0;
25014
+ stack[sp - 1] = stack[sp - 1] | 0 | b;
25015
+ break;
25016
+ }
25017
+ case OP.XOR: {
25018
+ const b = stack[--sp] | 0;
25019
+ stack[sp - 1] = (stack[sp - 1] | 0) ^ b;
25020
+ break;
25021
+ }
25022
+ case OP.ATAN: {
25023
+ const b = stack[--sp];
25024
+ const deg = Math.atan2(stack[sp - 1], b) * _RAD_TO_DEG;
25025
+ stack[sp - 1] = deg < 0 ? deg + 360 : deg;
25026
+ break;
25027
+ }
25028
+ case OP.MIN: {
25029
+ const b = stack[--sp];
25030
+ stack[sp - 1] = Math.min(stack[sp - 1], b);
25031
+ break;
25032
+ }
25033
+ case OP.MAX: {
25034
+ const b = stack[--sp];
25035
+ stack[sp - 1] = Math.max(stack[sp - 1], b);
25036
+ break;
25037
+ }
25038
+ case OP.TEE_TMP:
25039
+ tmp[ir[ip++] | 0] = stack[sp - 1];
25040
+ break;
25041
+ case OP.LOAD_TMP:
25042
+ stack[sp++] = tmp[ir[ip++] | 0];
25043
+ break;
25044
+ }
25045
+ }
25046
+ }
25047
+ };
25048
+ var PSStackBasedInterpreter = class {
25049
+ // Safe: JS is single-threaded.
25050
+ static #stack = new Float64Array(100);
25051
+ static #sp = 0;
25052
+ static #push(v) {
25053
+ if (this.#sp < this.#stack.length) {
25054
+ this.#stack[this.#sp++] = v;
25055
+ }
25056
+ }
25057
+ static #execOp(op) {
25058
+ const stack = this.#stack;
25059
+ switch (op) {
25060
+ case TOKEN.true:
25061
+ this.#push(1);
25062
+ break;
25063
+ case TOKEN.false:
25064
+ this.#push(0);
25065
+ break;
25066
+ case TOKEN.abs:
25067
+ stack[this.#sp - 1] = Math.abs(stack[this.#sp - 1]);
25068
+ break;
25069
+ case TOKEN.neg:
25070
+ stack[this.#sp - 1] = -stack[this.#sp - 1];
25071
+ break;
25072
+ case TOKEN.ceiling:
25073
+ stack[this.#sp - 1] = Math.ceil(stack[this.#sp - 1]);
25074
+ break;
25075
+ case TOKEN.floor:
25076
+ stack[this.#sp - 1] = Math.floor(stack[this.#sp - 1]);
25077
+ break;
25078
+ case TOKEN.round:
25079
+ stack[this.#sp - 1] = Math.floor(stack[this.#sp - 1] + 0.5);
25080
+ break;
25081
+ case TOKEN.truncate:
25082
+ stack[this.#sp - 1] = Math.trunc(stack[this.#sp - 1]);
25083
+ break;
25084
+ case TOKEN.sqrt:
25085
+ stack[this.#sp - 1] = Math.sqrt(stack[this.#sp - 1]);
25086
+ break;
25087
+ case TOKEN.sin:
25088
+ stack[this.#sp - 1] = Math.sin(
25089
+ stack[this.#sp - 1] % 360 * _DEG_TO_RAD
25090
+ );
25091
+ break;
25092
+ case TOKEN.cos:
25093
+ stack[this.#sp - 1] = Math.cos(
25094
+ stack[this.#sp - 1] % 360 * _DEG_TO_RAD
25095
+ );
25096
+ break;
25097
+ case TOKEN.ln:
25098
+ stack[this.#sp - 1] = Math.log(stack[this.#sp - 1]);
25099
+ break;
25100
+ case TOKEN.log:
25101
+ stack[this.#sp - 1] = Math.log10(stack[this.#sp - 1]);
25102
+ break;
25103
+ case TOKEN.cvi:
25104
+ stack[this.#sp - 1] = Math.trunc(stack[this.#sp - 1]) | 0;
25105
+ break;
25106
+ case TOKEN.cvr:
25107
+ break;
25108
+ // values are already f64
25109
+ case TOKEN.not: {
25110
+ const v = stack[this.#sp - 1];
25111
+ stack[this.#sp - 1] = v === 0 || v === 1 ? 1 - v : ~(v | 0);
25112
+ break;
25113
+ }
25114
+ case TOKEN.add: {
25115
+ const b = stack[--this.#sp];
25116
+ stack[this.#sp - 1] += b;
25117
+ break;
25118
+ }
25119
+ case TOKEN.sub: {
25120
+ const b = stack[--this.#sp];
25121
+ stack[this.#sp - 1] -= b;
25122
+ break;
25123
+ }
25124
+ case TOKEN.mul: {
25125
+ const b = stack[--this.#sp];
25126
+ stack[this.#sp - 1] *= b;
25127
+ break;
25128
+ }
25129
+ case TOKEN.div: {
25130
+ const b = stack[--this.#sp];
25131
+ stack[this.#sp - 1] = b !== 0 ? stack[this.#sp - 1] / b : 0;
25132
+ break;
25133
+ }
25134
+ case TOKEN.idiv: {
25135
+ const b = stack[--this.#sp];
25136
+ stack[this.#sp - 1] = b !== 0 ? Math.trunc(stack[this.#sp - 1] / b) : 0;
25137
+ break;
25138
+ }
25139
+ case TOKEN.mod: {
25140
+ const b = stack[--this.#sp];
25141
+ stack[this.#sp - 1] = b !== 0 ? stack[this.#sp - 1] % b : 0;
25142
+ break;
25143
+ }
25144
+ case TOKEN.exp: {
25145
+ const b = stack[--this.#sp];
25146
+ stack[this.#sp - 1] **= b;
25147
+ break;
25148
+ }
25149
+ case TOKEN.atan: {
25150
+ const dx = stack[--this.#sp];
25151
+ const deg = Math.atan2(stack[this.#sp - 1], dx) * _RAD_TO_DEG;
25152
+ stack[this.#sp - 1] = deg < 0 ? deg + 360 : deg;
25153
+ break;
25154
+ }
25155
+ case TOKEN.eq: {
25156
+ const b = stack[--this.#sp];
25157
+ stack[this.#sp - 1] = stack[this.#sp - 1] === b ? 1 : 0;
25158
+ break;
25159
+ }
25160
+ case TOKEN.ne: {
25161
+ const b = stack[--this.#sp];
25162
+ stack[this.#sp - 1] = stack[this.#sp - 1] !== b ? 1 : 0;
25163
+ break;
25164
+ }
25165
+ case TOKEN.gt: {
25166
+ const b = stack[--this.#sp];
25167
+ stack[this.#sp - 1] = stack[this.#sp - 1] > b ? 1 : 0;
25168
+ break;
25169
+ }
25170
+ case TOKEN.ge: {
25171
+ const b = stack[--this.#sp];
25172
+ stack[this.#sp - 1] = stack[this.#sp - 1] >= b ? 1 : 0;
25173
+ break;
25174
+ }
25175
+ case TOKEN.lt: {
25176
+ const b = stack[--this.#sp];
25177
+ stack[this.#sp - 1] = stack[this.#sp - 1] < b ? 1 : 0;
25178
+ break;
25179
+ }
25180
+ case TOKEN.le: {
25181
+ const b = stack[--this.#sp];
25182
+ stack[this.#sp - 1] = stack[this.#sp - 1] <= b ? 1 : 0;
25183
+ break;
25184
+ }
25185
+ case TOKEN.and: {
25186
+ const b = stack[--this.#sp] | 0;
25187
+ stack[this.#sp - 1] = (stack[this.#sp - 1] | 0) & b;
25188
+ break;
25189
+ }
25190
+ case TOKEN.or: {
25191
+ const b = stack[--this.#sp] | 0;
25192
+ stack[this.#sp - 1] = stack[this.#sp - 1] | 0 | b;
25193
+ break;
25194
+ }
25195
+ case TOKEN.xor: {
25196
+ const b = stack[--this.#sp] | 0;
25197
+ stack[this.#sp - 1] = (stack[this.#sp - 1] | 0) ^ b;
25198
+ break;
25199
+ }
25200
+ case TOKEN.bitshift: {
25201
+ const amt = stack[--this.#sp] | 0;
25202
+ const v = stack[this.#sp - 1] | 0;
25203
+ stack[this.#sp - 1] = amt > 0 ? v << amt : v >> -amt;
25204
+ break;
25205
+ }
25206
+ case TOKEN.min: {
25207
+ const b = stack[--this.#sp];
25208
+ stack[this.#sp - 1] = Math.min(stack[this.#sp - 1], b);
25209
+ break;
25210
+ }
25211
+ case TOKEN.max: {
25212
+ const b = stack[--this.#sp];
25213
+ stack[this.#sp - 1] = Math.max(stack[this.#sp - 1], b);
25214
+ break;
25215
+ }
25216
+ case TOKEN.dup:
25217
+ this.#push(stack[this.#sp - 1]);
25218
+ break;
25219
+ case TOKEN.exch: {
25220
+ const a = stack[--this.#sp];
25221
+ const b = stack[--this.#sp];
25222
+ this.#push(a);
25223
+ this.#push(b);
25224
+ break;
25225
+ }
25226
+ case TOKEN.pop:
25227
+ this.#sp--;
25228
+ break;
25229
+ case TOKEN.copy: {
25230
+ const n = Math.trunc(stack[--this.#sp]);
25231
+ const base = this.#sp - n;
25232
+ for (let k = 0; k < n; k++) {
25233
+ this.#push(stack[base + k]);
25234
+ }
25235
+ break;
25236
+ }
25237
+ case TOKEN.index: {
25238
+ const i = Math.trunc(stack[--this.#sp]);
25239
+ this.#push(stack[this.#sp - 1 - i]);
25240
+ break;
25241
+ }
25242
+ case TOKEN.roll: {
25243
+ const j = Math.trunc(stack[--this.#sp]);
25244
+ const n = Math.trunc(stack[--this.#sp]);
25245
+ if (n > 1 && j !== 0) {
25246
+ const mod = (j % n + n) % n;
25247
+ if (mod !== 0) {
25248
+ const base = this.#sp - n;
25249
+ const sub = stack.slice(base, this.#sp);
25250
+ for (let k = 0; k < n; k++) {
25251
+ stack[base + k] = sub[(k - mod + n) % n];
25252
+ }
25253
+ }
25254
+ }
25255
+ break;
25256
+ }
25257
+ }
25258
+ }
25259
+ static #execBlock(instructions) {
25260
+ for (const instr of instructions) {
25261
+ switch (instr.type) {
25262
+ case PS_NODE.number:
25263
+ this.#push(instr.value);
25264
+ break;
25265
+ case PS_NODE.operator:
25266
+ this.#execOp(instr.op);
25267
+ break;
25268
+ case PS_NODE.if:
25269
+ if (this.#stack[--this.#sp] !== 0) {
25270
+ this.#execBlock(instr.then.instructions);
25271
+ }
25272
+ break;
25273
+ case PS_NODE.ifelse:
25274
+ if (this.#stack[--this.#sp] !== 0) {
25275
+ this.#execBlock(instr.then.instructions);
25276
+ } else {
25277
+ this.#execBlock(instr.otherwise.instructions);
25278
+ }
25279
+ break;
25280
+ }
25281
+ }
25282
+ }
25283
+ /**
25284
+ * @param {import("./ast.js").PsProgram} program
25285
+ * @param {number[]} domain – flat [min0,max0, …]
25286
+ * @param {number[]} range – flat [min0,max0, …]
25287
+ * @returns {Function} – `(src, srcOffset, dest, destOffset) => void`
25288
+ */
25289
+ static build(program, domain, range) {
25290
+ const nIn = domain.length >> 1;
25291
+ const nOut = range.length >> 1;
25292
+ const { instructions } = program.body;
25293
+ return (src, srcOffset, dest, destOffset) => {
25294
+ this.#sp = 0;
25295
+ for (let i = 0; i < nIn; i++) {
25296
+ this.#push(src[srcOffset + i]);
25297
+ }
25298
+ this.#execBlock(instructions);
25299
+ const base = this.#sp - nOut;
25300
+ for (let i = 0; i < nOut; i++) {
25301
+ const v = base + i >= 0 ? this.#stack[base + i] : 0;
25302
+ dest[destOffset + i] = MathClamp(v, range[i * 2], range[i * 2 + 1]);
25303
+ }
25304
+ };
25305
+ }
25306
+ };
25307
+ function buildPostScriptJsFunction(source, domain, range, forceInterpreter = false) {
25308
+ const program = parsePostScriptFunction(source);
25309
+ const ir = !forceInterpreter && new PsJsCompiler(domain, range).compile(program);
25310
+ if (ir) {
25311
+ return (src, srcOffset, dest, destOffset) => {
25312
+ PsJsCompiler.execute(ir, src, srcOffset, dest, destOffset);
25313
+ };
25314
+ }
25315
+ return PSStackBasedInterpreter.build(program, domain, range);
25316
+ }
22709
25317
  var PdfError = class extends Error {
22710
25318
  constructor(code, message) {
22711
25319
  super(message);
@@ -33785,6 +36393,25 @@ var __webpack_exports__JpxImage = __webpack_exports__.JpxImage;
33785
36393
  var __webpack_exports__VerbosityLevel = __webpack_exports__.VerbosityLevel;
33786
36394
  var __webpack_exports__getVerbosityLevel = __webpack_exports__.getVerbosityLevel;
33787
36395
  var __webpack_exports__setVerbosityLevel = __webpack_exports__.setVerbosityLevel;
36396
+ function createCalibratedColorSpace(doc, family, parameters) {
36397
+ const dict = doc.resolveDict(parameters);
36398
+ const array = (key) => {
36399
+ const value = dict ? doc.resolveArray(dictGet(dict, key)) : void 0;
36400
+ return value?.items.map((item) => {
36401
+ const number = doc.resolve(item);
36402
+ return number?.kind === "number" ? number.value : 0;
36403
+ });
36404
+ };
36405
+ const whitePoint = array("WhitePoint") ?? [0.95047, 1, 1.08883];
36406
+ const blackPoint = array("BlackPoint");
36407
+ if (family === "CalGray") {
36408
+ const gamma = dict ? doc.resolve(dictGet(dict, "Gamma")) : void 0;
36409
+ return new CalGrayCS(whitePoint, blackPoint, gamma?.kind === "number" ? gamma.value : void 0);
36410
+ }
36411
+ if (family === "CalRGB") return new CalRGBCS(whitePoint, blackPoint, array("Gamma"), array("Matrix"));
36412
+ return new LabCS(whitePoint, blackPoint, array("Range"));
36413
+ }
36414
+ var cmykColorSpace = new DeviceCmykCS();
33788
36415
  function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
33789
36416
  if (!csNode) return { colorSpace: "rgb", colorSpaceLabel: "rgb", components: 3 };
33790
36417
  const resolved = doc.resolve(csNode);
@@ -33825,7 +36452,7 @@ function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
33825
36452
  palette = lookupNode.bytes;
33826
36453
  }
33827
36454
  let resolvedBaseComp = baseInfo.components;
33828
- if (palette && (baseInfo.isLab || baseInfo.isSeparation || baseInfo.isDeviceN || baseInfo.calRgbGamma !== void 0 || baseInfo.calGrayGamma !== void 0)) {
36455
+ if (palette && (baseInfo.isSeparation || baseInfo.isDeviceN || baseInfo.calibrated !== void 0)) {
33829
36456
  const numEntries = Math.max(1, Math.min(hival + 1, Math.floor(palette.length / Math.max(1, baseInfo.components))));
33830
36457
  const rgbaPal = decodeSamplesToRgba(palette, numEntries, 1, 8, baseInfo);
33831
36458
  const rgbPal = new Uint8Array(numEntries * 3);
@@ -33855,74 +36482,21 @@ function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
33855
36482
  }
33856
36483
  return { colorSpace: "rgb", colorSpaceLabel: "icc", components: 3 };
33857
36484
  }
33858
- if (kindName === "CalGray") {
33859
- const calDict = doc.resolveDict(resolved.items[1]);
33860
- const gammaNode = calDict ? doc.resolve(dictGet(calDict, "Gamma")) : void 0;
33861
- const gamma = gammaNode?.kind === "number" && gammaNode.value > 0 ? gammaNode.value : 1;
33862
- return { colorSpace: "gray", colorSpaceLabel: "cal-gray", components: 1, calGrayGamma: gamma };
33863
- }
33864
- if (kindName === "CalRGB") {
33865
- const calDict = doc.resolveDict(resolved.items[1]);
33866
- const gammaArr = calDict ? doc.resolveArray(dictGet(calDict, "Gamma")) : void 0;
33867
- let calRgbGamma = [1, 1, 1];
33868
- if (gammaArr && gammaArr.items.length >= 3) {
33869
- const gNums = gammaArr.items.slice(0, 3).map((it) => {
33870
- const r = doc.resolve(it);
33871
- return r?.kind === "number" && r.value > 0 ? r.value : 1;
33872
- });
33873
- calRgbGamma = [gNums[0], gNums[1], gNums[2]];
33874
- }
33875
- const matArr = calDict ? doc.resolveArray(dictGet(calDict, "Matrix")) : void 0;
33876
- let calRgbMatrix;
33877
- if (matArr && matArr.items.length >= 9) {
33878
- calRgbMatrix = matArr.items.slice(0, 9).map((it) => {
33879
- const r = doc.resolve(it);
33880
- return r?.kind === "number" ? r.value : 0;
33881
- });
33882
- }
36485
+ if (kindName === "CalGray" || kindName === "CalRGB" || kindName === "Lab") {
36486
+ const calibrated = createCalibratedColorSpace(doc, kindName, resolved.items[1]);
33883
36487
  return {
33884
- colorSpace: "rgb",
33885
- colorSpaceLabel: "cal-rgb",
33886
- components: 3,
33887
- calRgbGamma,
33888
- calRgbMatrix
36488
+ colorSpace: kindName === "CalGray" ? "gray" : "rgb",
36489
+ colorSpaceLabel: kindName === "CalGray" ? "cal-gray" : kindName === "CalRGB" ? "cal-rgb" : "lab",
36490
+ components: kindName === "CalGray" ? 1 : 3,
36491
+ calibrated
33889
36492
  };
33890
36493
  }
33891
- if (kindName === "Lab") {
33892
- const labDict = doc.resolveDict(resolved.items[1]);
33893
- const rangeArr = labDict ? doc.resolveArray(dictGet(labDict, "Range")) : void 0;
33894
- let labRange = [-100, 100, -100, 100];
33895
- if (rangeArr && rangeArr.items.length >= 4) {
33896
- const nums = rangeArr.items.slice(0, 4).map((it) => {
33897
- const r = doc.resolve(it);
33898
- return r?.kind === "number" ? r.value : 0;
33899
- });
33900
- labRange = [nums[0], nums[1], nums[2], nums[3]];
33901
- }
33902
- return { colorSpace: "rgb", colorSpaceLabel: "lab", components: 3, isLab: true, labRange };
33903
- }
33904
36494
  if (kindName === "Separation" || kindName === "DeviceN") {
33905
36495
  const isDevN = kindName === "DeviceN";
33906
36496
  const namesArr = isDevN ? doc.resolveArray(resolved.items[1]) : void 0;
33907
36497
  const devNComponents = isDevN && namesArr ? Math.max(1, namesArr.items.length) : 1;
33908
36498
  const altInfo = resolveColorSpaceInfo(doc, resolved.items[2], resourcesDict);
33909
36499
  const altSpace = altInfo.colorSpace === "cmyk" ? "cmyk" : altInfo.colorSpace === "gray" ? "gray" : "rgb";
33910
- const fnResolved = doc.resolve(resolved.items[3]);
33911
- const fnDict = fnResolved?.kind === "stream" ? fnResolved.dict : fnResolved?.kind === "dict" ? fnResolved : void 0;
33912
- const ftNode = fnDict ? doc.resolve(dictGet(fnDict, "FunctionType")) : void 0;
33913
- const tintFunctionType = ftNode?.kind === "number" ? ftNode.value : 2;
33914
- const c0Arr = fnDict ? doc.resolveArray(dictGet(fnDict, "C0")) : void 0;
33915
- const c1Arr = fnDict ? doc.resolveArray(dictGet(fnDict, "C1")) : void 0;
33916
- const nNode = fnDict ? doc.resolve(dictGet(fnDict, "N")) : void 0;
33917
- const c0 = c0Arr ? c0Arr.items.map((it) => {
33918
- const r = doc.resolve(it);
33919
- return r?.kind === "number" ? r.value : 0;
33920
- }) : altSpace === "cmyk" ? [0, 0, 0, 0] : altSpace === "gray" ? [1] : [1, 1, 1];
33921
- const c1 = c1Arr ? c1Arr.items.map((it) => {
33922
- const r = doc.resolve(it);
33923
- return r?.kind === "number" ? r.value : 0;
33924
- }) : altSpace === "cmyk" ? [0, 0, 0, 1] : altSpace === "gray" ? [0] : [0, 0, 0];
33925
- const sepN = nNode?.kind === "number" && nNode.value > 0 ? nNode.value : 1;
33926
36500
  return {
33927
36501
  colorSpace: altSpace,
33928
36502
  colorSpaceLabel: isDevN ? "devn" : "sep",
@@ -33930,12 +36504,9 @@ function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
33930
36504
  isSeparation: !isDevN,
33931
36505
  isDeviceN: isDevN,
33932
36506
  separationAltSpace: altSpace,
33933
- separationC0: c0,
33934
- separationC1: c1,
33935
- separationN: sepN,
36507
+ alternateCalibrated: altInfo.calibrated,
33936
36508
  tintFunctionDoc: doc,
33937
- tintFunctionNode: resolved.items[3],
33938
- tintFunctionType
36509
+ tintFunctionNode: resolved.items[3]
33939
36510
  };
33940
36511
  }
33941
36512
  }
@@ -34085,141 +36656,55 @@ function decodeSamplesToRgba(rawSamples, width, height, bpc, csInfo, alphaSample
34085
36656
  const rgba = new Uint8Array(width * height * 4);
34086
36657
  const pixelCount = width * height;
34087
36658
  if (csInfo.isSeparation || csInfo.isDeviceN) {
34088
- const c0 = csInfo.separationC0 ?? [1, 1, 1];
34089
- const c1 = csInfo.separationC1 ?? [0, 0, 0];
34090
- const expN = csInfo.separationN ?? 1;
34091
36659
  const alt = csInfo.separationAltSpace ?? "rgb";
34092
36660
  const numCh = Math.max(1, csInfo.components);
34093
36661
  const step = bpc === 16 ? 2 : 1;
34094
- const useGenericTintFn = csInfo.tintFunctionDoc !== void 0 && csInfo.tintFunctionNode !== void 0 && (csInfo.tintFunctionType === 0 || csInfo.tintFunctionType === 3 || csInfo.tintFunctionType === 4);
34095
36662
  for (let p = 0; p < pixelCount; p++) {
34096
36663
  const chVals = [];
34097
- let wSum = 0;
34098
36664
  for (let ch3 = 0; ch3 < numCh; ch3++) {
34099
36665
  const sRaw = (rawSamples[(p * numCh + ch3) * step] ?? 0) / 255;
34100
- const tRemapped = remapUnitSampleWithDecode(sRaw, ch3, decodePairs);
34101
- chVals.push(tRemapped);
34102
- wSum += Math.pow(Math.max(0, Math.min(1, tRemapped)), expN);
34103
- }
34104
- if (useGenericTintFn) {
34105
- const outComps = evalShadingFunctionToComponents(
34106
- csInfo.tintFunctionDoc,
34107
- csInfo.tintFunctionNode,
34108
- chVals
34109
- );
34110
- if (alt === "cmyk") {
34111
- const c = outComps[0] ?? 0;
34112
- const m = outComps[1] ?? 0;
34113
- const y = outComps[2] ?? 0;
34114
- const k = outComps[3] ?? 0;
34115
- rgba[p * 4] = Math.round(Math.max(0, Math.min(1, (1 - c) * (1 - k))) * 255);
34116
- rgba[p * 4 + 1] = Math.round(Math.max(0, Math.min(1, (1 - m) * (1 - k))) * 255);
34117
- rgba[p * 4 + 2] = Math.round(Math.max(0, Math.min(1, (1 - y) * (1 - k))) * 255);
34118
- } else if (alt === "gray") {
34119
- const gByte = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
34120
- rgba[p * 4] = gByte;
34121
- rgba[p * 4 + 1] = gByte;
34122
- rgba[p * 4 + 2] = gByte;
34123
- } else {
34124
- rgba[p * 4] = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
34125
- rgba[p * 4 + 1] = Math.round(Math.max(0, Math.min(1, outComps[1] ?? 0)) * 255);
34126
- rgba[p * 4 + 2] = Math.round(Math.max(0, Math.min(1, outComps[2] ?? 0)) * 255);
34127
- }
34128
- rgba[p * 4 + 3] = 255;
34129
- continue;
36666
+ chVals.push(remapUnitSampleWithDecode(sRaw, ch3, decodePairs));
34130
36667
  }
34131
- const w = Math.max(0, Math.min(1, wSum));
34132
- if (alt === "cmyk") {
34133
- const c = (c0[0] ?? 0) + w * ((c1[0] ?? 0) - (c0[0] ?? 0));
34134
- const m = (c0[1] ?? 0) + w * ((c1[1] ?? 0) - (c0[1] ?? 0));
34135
- const y = (c0[2] ?? 0) + w * ((c1[2] ?? 0) - (c0[2] ?? 0));
34136
- const k = (c0[3] ?? 0) + w * ((c1[3] ?? 1) - (c0[3] ?? 0));
34137
- rgba[p * 4] = Math.round(Math.max(0, Math.min(1, (1 - c) * (1 - k))) * 255);
34138
- rgba[p * 4 + 1] = Math.round(Math.max(0, Math.min(1, (1 - m) * (1 - k))) * 255);
34139
- rgba[p * 4 + 2] = Math.round(Math.max(0, Math.min(1, (1 - y) * (1 - k))) * 255);
36668
+ const outComps = evalShadingFunctionToComponents(
36669
+ csInfo.tintFunctionDoc,
36670
+ csInfo.tintFunctionNode,
36671
+ chVals
36672
+ );
36673
+ if (csInfo.alternateCalibrated) {
36674
+ rgba.set(csInfo.alternateCalibrated.getRgb(outComps, 0), p * 4);
36675
+ } else if (alt === "cmyk") {
36676
+ rgba.set(cmykColorSpace.getRgb([outComps[0] ?? 0, outComps[1] ?? 0, outComps[2] ?? 0, outComps[3] ?? 0], 0), p * 4);
34140
36677
  } else if (alt === "gray") {
34141
- const gVal = (c0[0] ?? 1) + w * ((c1[0] ?? 0) - (c0[0] ?? 1));
34142
- const gByte = Math.round(Math.max(0, Math.min(1, gVal)) * 255);
36678
+ const gByte = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
34143
36679
  rgba[p * 4] = gByte;
34144
36680
  rgba[p * 4 + 1] = gByte;
34145
36681
  rgba[p * 4 + 2] = gByte;
34146
36682
  } else {
34147
- const rVal = (c0[0] ?? 1) + w * ((c1[0] ?? 0) - (c0[0] ?? 1));
34148
- const gVal = (c0[1] ?? 1) + w * ((c1[1] ?? 0) - (c0[1] ?? 1));
34149
- const bVal = (c0[2] ?? 1) + w * ((c1[2] ?? 0) - (c0[2] ?? 1));
34150
- rgba[p * 4] = Math.round(Math.max(0, Math.min(1, rVal)) * 255);
34151
- rgba[p * 4 + 1] = Math.round(Math.max(0, Math.min(1, gVal)) * 255);
34152
- rgba[p * 4 + 2] = Math.round(Math.max(0, Math.min(1, bVal)) * 255);
36683
+ rgba[p * 4] = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
36684
+ rgba[p * 4 + 1] = Math.round(Math.max(0, Math.min(1, outComps[1] ?? 0)) * 255);
36685
+ rgba[p * 4 + 2] = Math.round(Math.max(0, Math.min(1, outComps[2] ?? 0)) * 255);
34153
36686
  }
34154
36687
  rgba[p * 4 + 3] = 255;
34155
36688
  }
34156
- } else if (csInfo.isLab) {
34157
- const [amin, amax, bmin, bmax] = csInfo.labRange ?? [-100, 100, -100, 100];
34158
- const invF = (t) => t > 6 / 29 ? t * t * t : 3 * (6 / 29) * (6 / 29) * (t - 4 / 29);
34159
- const toSrgb = (u) => {
34160
- const c = u <= 31308e-7 ? 12.92 * u : 1.055 * Math.pow(u, 1 / 2.4) - 0.055;
34161
- return Math.round(Math.max(0, Math.min(1, c)) * 255);
34162
- };
36689
+ } else if (csInfo.calibrated?.name === "Lab") {
36690
+ const { amin, amax, bmin, bmax } = csInfo.calibrated;
36691
+ const step = bpc === 16 ? 2 : 1;
34163
36692
  for (let p = 0; p < pixelCount; p++) {
34164
- const s0 = (rawSamples[p * 3] ?? 0) / 255;
34165
- const s1 = (rawSamples[p * 3 + 1] ?? 128) / 255;
34166
- const s2 = (rawSamples[p * 3 + 2] ?? 128) / 255;
34167
- const L = s0 * 100;
34168
- if (L <= 0.01) {
34169
- rgba[p * 4] = 0;
34170
- rgba[p * 4 + 1] = 0;
34171
- rgba[p * 4 + 2] = 0;
34172
- rgba[p * 4 + 3] = 255;
34173
- continue;
34174
- }
34175
- const a = amin + s1 * (amax - amin);
34176
- const b = bmin + s2 * (bmax - bmin);
34177
- const fy = (L + 16) / 116;
34178
- const fx = fy + a / 500;
34179
- const fz = fy - b / 200;
34180
- const X = 0.95047 * invF(fx);
34181
- const Y = 1 * invF(fy);
34182
- const Z = 1.08883 * invF(fz);
34183
- const linR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
34184
- const linG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
34185
- const linB = X * 0.0557 + Y * -0.204 + Z * 1.057;
34186
- rgba[p * 4] = toSrgb(linR);
34187
- rgba[p * 4 + 1] = toSrgb(linG);
34188
- rgba[p * 4 + 2] = toSrgb(linB);
36693
+ const L = (rawSamples[p * 3 * step] ?? 0) / 255 * 100;
36694
+ const a = amin + (rawSamples[(p * 3 + 1) * step] ?? 128) / 255 * (amax - amin);
36695
+ const b = bmin + (rawSamples[(p * 3 + 2) * step] ?? 128) / 255 * (bmax - bmin);
36696
+ rgba.set(csInfo.calibrated.getRgb([L, a, b], 0), p * 4);
34189
36697
  rgba[p * 4 + 3] = 255;
34190
36698
  }
34191
36699
  } else if (csInfo.colorSpace === "rgb") {
34192
- const hasCalRgb = Boolean(csInfo.calRgbGamma || csInfo.calRgbMatrix);
34193
- const toSrgbByte = (u) => {
34194
- const c = u <= 31308e-7 ? 12.92 * u : 1.055 * Math.pow(u, 1 / 2.4) - 0.055;
34195
- return Math.round(Math.max(0, Math.min(1, c)) * 255);
34196
- };
34197
36700
  const writeRgbPixel = (p, rByte, gByte, bByte) => {
34198
- let rU = remapUnitSampleWithDecode(rByte / 255, 0, decodePairs);
34199
- let gU = remapUnitSampleWithDecode(gByte / 255, 1, decodePairs);
34200
- let bU = remapUnitSampleWithDecode(bByte / 255, 2, decodePairs);
34201
- if (hasCalRgb) {
34202
- const [gr, gg, gb] = csInfo.calRgbGamma ?? [1, 1, 1];
34203
- const ag = Math.pow(rU, gr);
34204
- const bg = Math.pow(gU, gg);
34205
- const cg = Math.pow(bU, gb);
34206
- if (csInfo.calRgbMatrix && csInfo.calRgbMatrix.length >= 9) {
34207
- const m = csInfo.calRgbMatrix;
34208
- const X = m[0] * ag + m[3] * bg + m[6] * cg;
34209
- const Y = m[1] * ag + m[4] * bg + m[7] * cg;
34210
- const Z = m[2] * ag + m[5] * bg + m[8] * cg;
34211
- const linR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
34212
- const linG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
34213
- const linB = X * 0.0557 + Y * -0.204 + Z * 1.057;
34214
- rgba[p * 4] = toSrgbByte(linR);
34215
- rgba[p * 4 + 1] = toSrgbByte(linG);
34216
- rgba[p * 4 + 2] = toSrgbByte(linB);
34217
- rgba[p * 4 + 3] = 255;
34218
- return;
34219
- }
34220
- rU = ag;
34221
- gU = bg;
34222
- bU = cg;
36701
+ const rU = remapUnitSampleWithDecode(rByte / 255, 0, decodePairs);
36702
+ const gU = remapUnitSampleWithDecode(gByte / 255, 1, decodePairs);
36703
+ const bU = remapUnitSampleWithDecode(bByte / 255, 2, decodePairs);
36704
+ if (csInfo.calibrated) {
36705
+ rgba.set(csInfo.calibrated.getRgb([rU, gU, bU], 0), p * 4);
36706
+ rgba[p * 4 + 3] = 255;
36707
+ return;
34223
36708
  }
34224
36709
  rgba[p * 4] = Math.round(rU * 255);
34225
36710
  rgba[p * 4 + 1] = Math.round(gU * 255);
@@ -34239,10 +36724,11 @@ function decodeSamplesToRgba(rawSamples, width, height, bpc, csInfo, alphaSample
34239
36724
  }
34240
36725
  } else if (csInfo.colorSpace === "gray") {
34241
36726
  const writeGrayPixel = (p, gByte) => {
34242
- let gU = remapUnitSampleWithDecode(gByte / 255, 0, decodePairs);
34243
- if (csInfo.calGrayGamma && csInfo.calGrayGamma !== 1) {
34244
- const lin = Math.pow(gU, csInfo.calGrayGamma);
34245
- gU = lin <= 31308e-7 ? 12.92 * lin : 1.055 * Math.pow(lin, 1 / 2.4) - 0.055;
36727
+ const gU = remapUnitSampleWithDecode(gByte / 255, 0, decodePairs);
36728
+ if (csInfo.calibrated) {
36729
+ rgba.set(csInfo.calibrated.getRgb([gU], 0), p * 4);
36730
+ rgba[p * 4 + 3] = 255;
36731
+ return;
34246
36732
  }
34247
36733
  const outG = Math.round(Math.max(0, Math.min(1, gU)) * 255);
34248
36734
  rgba[p * 4] = outG;
@@ -34298,9 +36784,7 @@ function decodeSamplesToRgba(rawSamples, width, height, bpc, csInfo, alphaSample
34298
36784
  const m = remapUnitSampleWithDecode((rawSamples[p * stride + chStep] ?? 0) / 255, 1, decodePairs);
34299
36785
  const y = remapUnitSampleWithDecode((rawSamples[p * stride + chStep * 2] ?? 0) / 255, 2, decodePairs);
34300
36786
  const k = remapUnitSampleWithDecode((rawSamples[p * stride + chStep * 3] ?? 0) / 255, 3, decodePairs);
34301
- rgba[p * 4] = Math.round((1 - c) * (1 - k) * 255);
34302
- rgba[p * 4 + 1] = Math.round((1 - m) * (1 - k) * 255);
34303
- rgba[p * 4 + 2] = Math.round((1 - y) * (1 - k) * 255);
36787
+ rgba.set(cmykColorSpace.getRgb([c, m, y, k], 0), p * 4);
34304
36788
  rgba[p * 4 + 3] = 255;
34305
36789
  }
34306
36790
  } else if (csInfo.colorSpace === "index") {
@@ -34338,9 +36822,7 @@ function decodeSamplesToRgba(rawSamples, width, height, bpc, csInfo, alphaSample
34338
36822
  const m = pal[idx * 4 + 1] / 255;
34339
36823
  const yel = pal[idx * 4 + 2] / 255;
34340
36824
  const k = pal[idx * 4 + 3] / 255;
34341
- rgba[p * 4] = Math.round((1 - c) * (1 - k) * 255);
34342
- rgba[p * 4 + 1] = Math.round((1 - m) * (1 - k) * 255);
34343
- rgba[p * 4 + 2] = Math.round((1 - yel) * (1 - k) * 255);
36825
+ rgba.set(cmykColorSpace.getRgb([c, m, yel, k], 0), p * 4);
34344
36826
  } else {
34345
36827
  rgba[p * 4] = pal[idx * baseComp];
34346
36828
  rgba[p * 4 + 1] = pal[idx * baseComp + 1];
@@ -34595,6 +37077,7 @@ function decodeInlineImageNodeToRgba(doc, dict, rawData, activeRes, fillColor) {
34595
37077
  });
34596
37078
  return decodeXObjectImageToRgba(context, { kind: "stream", dict, rawBytes: rawData }, activeRes, fillColor);
34597
37079
  }
37080
+ var cmykColorSpace2 = new DeviceCmykCS();
34598
37081
  function multiplyMatrices(m1, m2) {
34599
37082
  return [
34600
37083
  m1[0] * m2[0] + m1[1] * m2[2],
@@ -34811,193 +37294,7 @@ function resolvePageFonts(doc, resourcesDict) {
34811
37294
  }
34812
37295
  return fonts;
34813
37296
  }
34814
- function evaluateType4PostScriptTokens(tokens, initialStack) {
34815
- const stack = [...initialStack];
34816
- const runRange = (start, end) => {
34817
- let i = start;
34818
- while (i < end) {
34819
- const tok = tokens[i];
34820
- if (tok === "{") {
34821
- let depth = 1;
34822
- let j = i + 1;
34823
- while (j < end && depth > 0) {
34824
- if (tokens[j] === "{") depth++;
34825
- else if (tokens[j] === "}") depth--;
34826
- j++;
34827
- }
34828
- const blockStart = i + 1;
34829
- const blockEnd = j - 1;
34830
- if (j < end && tokens[j] === "{") {
34831
- let depth2 = 1;
34832
- let k = j + 1;
34833
- while (k < end && depth2 > 0) {
34834
- if (tokens[k] === "{") depth2++;
34835
- else if (tokens[k] === "}") depth2--;
34836
- k++;
34837
- }
34838
- if (k < end && tokens[k] === "ifelse") {
34839
- const cond = stack.pop() ?? 0;
34840
- if (cond !== 0) runRange(blockStart, blockEnd);
34841
- else runRange(j + 1, k - 1);
34842
- i = k + 1;
34843
- continue;
34844
- }
34845
- }
34846
- if (j < end && tokens[j] === "if") {
34847
- const cond = stack.pop() ?? 0;
34848
- if (cond !== 0) runRange(blockStart, blockEnd);
34849
- i = j + 1;
34850
- continue;
34851
- }
34852
- runRange(blockStart, blockEnd);
34853
- i = j;
34854
- continue;
34855
- }
34856
- if (tok === "}") {
34857
- i++;
34858
- continue;
34859
- }
34860
- const numVal2 = Number(tok);
34861
- if (tok.length > 0 && !Number.isNaN(numVal2)) {
34862
- stack.push(numVal2);
34863
- } else if (tok === "true") {
34864
- stack.push(1);
34865
- } else if (tok === "false") {
34866
- stack.push(0);
34867
- } else if (tok === "add") {
34868
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34869
- stack.push(a + b);
34870
- } else if (tok === "sub") {
34871
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34872
- stack.push(a - b);
34873
- } else if (tok === "mul") {
34874
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34875
- stack.push(a * b);
34876
- } else if (tok === "div") {
34877
- const b = stack.pop() ?? 1, a = stack.pop() ?? 0;
34878
- stack.push(Math.abs(b) > 1e-12 ? a / b : 0);
34879
- } else if (tok === "idiv") {
34880
- const b = stack.pop() ?? 1, a = stack.pop() ?? 0;
34881
- stack.push(Math.abs(b) > 1e-12 ? Math.trunc(a / b) : 0);
34882
- } else if (tok === "mod") {
34883
- const b = stack.pop() ?? 1, a = stack.pop() ?? 0;
34884
- stack.push(Math.abs(b) > 1e-12 ? a % b : 0);
34885
- } else if (tok === "neg") {
34886
- stack.push(-(stack.pop() ?? 0));
34887
- } else if (tok === "abs") {
34888
- stack.push(Math.abs(stack.pop() ?? 0));
34889
- } else if (tok === "ceiling") {
34890
- stack.push(Math.ceil(stack.pop() ?? 0));
34891
- } else if (tok === "floor") {
34892
- stack.push(Math.floor(stack.pop() ?? 0));
34893
- } else if (tok === "round") {
34894
- stack.push(Math.round(stack.pop() ?? 0));
34895
- } else if (tok === "truncate" || tok === "cvi") {
34896
- stack.push(Math.trunc(stack.pop() ?? 0));
34897
- } else if (tok === "sqrt") {
34898
- stack.push(Math.sqrt(Math.max(0, stack.pop() ?? 0)));
34899
- } else if (tok === "sin") {
34900
- stack.push(Math.sin((stack.pop() ?? 0) * Math.PI / 180));
34901
- } else if (tok === "cos") {
34902
- stack.push(Math.cos((stack.pop() ?? 0) * Math.PI / 180));
34903
- } else if (tok === "atan") {
34904
- const dx = stack.pop() ?? 1, dy = stack.pop() ?? 0;
34905
- let deg = Math.atan2(dy, dx) * 180 / Math.PI;
34906
- if (deg < 0) deg += 360;
34907
- stack.push(deg);
34908
- } else if (tok === "exp") {
34909
- const exp = stack.pop() ?? 1, base = stack.pop() ?? 0;
34910
- stack.push(Math.pow(base, exp));
34911
- } else if (tok === "ln") {
34912
- stack.push(Math.log(Math.max(1e-12, stack.pop() ?? 1)));
34913
- } else if (tok === "log") {
34914
- stack.push(Math.log10(Math.max(1e-12, stack.pop() ?? 1)));
34915
- } else if (tok === "dup") {
34916
- if (stack.length > 0) stack.push(stack[stack.length - 1]);
34917
- } else if (tok === "exch") {
34918
- if (stack.length >= 2) {
34919
- const b = stack.pop(), a = stack.pop();
34920
- stack.push(b, a);
34921
- }
34922
- } else if (tok === "pop") {
34923
- stack.pop();
34924
- } else if (tok === "copy") {
34925
- const n = Math.max(0, Math.trunc(stack.pop() ?? 0));
34926
- const slice = stack.slice(Math.max(0, stack.length - n));
34927
- stack.push(...slice);
34928
- } else if (tok === "index") {
34929
- const n = Math.max(0, Math.trunc(stack.pop() ?? 0));
34930
- const idx = stack.length - 1 - n;
34931
- if (idx >= 0 && idx < stack.length) stack.push(stack[idx]);
34932
- } else if (tok === "roll") {
34933
- const jShift = Math.trunc(stack.pop() ?? 0);
34934
- const n = Math.max(0, Math.trunc(stack.pop() ?? 0));
34935
- if (n > 0 && stack.length >= n) {
34936
- const sub = stack.splice(stack.length - n, n);
34937
- const modShift = (jShift % n + n) % n;
34938
- const rolled = [...sub.slice(n - modShift), ...sub.slice(0, n - modShift)];
34939
- stack.push(...rolled);
34940
- }
34941
- } else if (tok === "eq") {
34942
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34943
- stack.push(Math.abs(a - b) < 1e-9 ? 1 : 0);
34944
- } else if (tok === "ne") {
34945
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34946
- stack.push(Math.abs(a - b) >= 1e-9 ? 1 : 0);
34947
- } else if (tok === "gt") {
34948
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34949
- stack.push(a > b ? 1 : 0);
34950
- } else if (tok === "ge") {
34951
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34952
- stack.push(a >= b ? 1 : 0);
34953
- } else if (tok === "lt") {
34954
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34955
- stack.push(a < b ? 1 : 0);
34956
- } else if (tok === "le") {
34957
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34958
- stack.push(a <= b ? 1 : 0);
34959
- } else if (tok === "and") {
34960
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34961
- stack.push(a !== 0 && b !== 0 ? 1 : 0);
34962
- } else if (tok === "or") {
34963
- const b = stack.pop() ?? 0, a = stack.pop() ?? 0;
34964
- stack.push(a !== 0 || b !== 0 ? 1 : 0);
34965
- } else if (tok === "not") {
34966
- const a = stack.pop() ?? 0;
34967
- stack.push(a === 0 ? 1 : 0);
34968
- }
34969
- i++;
34970
- }
34971
- };
34972
- runRange(0, tokens.length);
34973
- return stack;
34974
- }
34975
- function tokenizePostScriptCode(bytes) {
34976
- const tokens = [];
34977
- let cur = "";
34978
- for (let i = 0; i < bytes.length; i++) {
34979
- const ch3 = String.fromCharCode(bytes[i]);
34980
- if (ch3 === "{" || ch3 === "}") {
34981
- if (cur.length > 0) {
34982
- tokens.push(cur);
34983
- cur = "";
34984
- }
34985
- tokens.push(ch3);
34986
- } else if (ch3 === " " || ch3 === " " || ch3 === "\n" || ch3 === "\r") {
34987
- if (cur.length > 0) {
34988
- tokens.push(cur);
34989
- cur = "";
34990
- }
34991
- } else {
34992
- cur += ch3;
34993
- }
34994
- }
34995
- if (cur.length > 0) tokens.push(cur);
34996
- if (tokens[0] === "{" && tokens[tokens.length - 1] === "}") {
34997
- return tokens.slice(1, -1);
34998
- }
34999
- return tokens;
35000
- }
37297
+ var postScriptFunctions = /* @__PURE__ */ new WeakMap();
35001
37298
  function evalShadingFunctionToComponents(doc, fnNode, inputs) {
35002
37299
  const inArr = typeof inputs === "number" ? [inputs] : inputs;
35003
37300
  const t = inArr[0] ?? 0;
@@ -35044,35 +37341,50 @@ function evalShadingFunctionToComponents(doc, fnNode, inputs) {
35044
37341
  const decode = getNums("Decode", range);
35045
37342
  const nOut = Math.max(1, Math.floor((decode.length || range.length || 6) / 2));
35046
37343
  const mIn = Math.max(1, size.length);
35047
- let flatGridIndex = 0;
37344
+ const streamBytes = doc.decodeStream(resolved);
37345
+ let vertices = [{ index: 0, weight: 1 }];
35048
37346
  let stride = 1;
35049
37347
  for (let i = 0; i < mIn; i++) {
35050
37348
  const d02 = dom[i * 2] ?? 0;
35051
37349
  const d12 = dom[i * 2 + 1] ?? 1;
35052
- const sMax = Math.max(1, (size[i] ?? 2) - 1);
37350
+ const sMax = Math.max(0, (size[i] ?? 2) - 1);
35053
37351
  const e0 = encode[i * 2] ?? 0;
35054
37352
  const e1 = encode[i * 2 + 1] ?? sMax;
35055
37353
  const x = Math.max(d02, Math.min(d12, inArr[i] ?? 0));
35056
- const u = Math.abs(d12 - d02) > 1e-8 ? (x - d02) / (d12 - d02) : 0;
35057
- const idx = Math.round(Math.max(0, Math.min(sMax, e0 + u * (e1 - e0))));
35058
- flatGridIndex += idx * stride;
37354
+ const u = d12 === d02 ? 0 : (x - d02) / (d12 - d02);
37355
+ const e = Math.max(0, Math.min(sMax, e0 + u * (e1 - e0)));
37356
+ const low = Math.floor(e), fraction = e - low;
37357
+ const next = [];
37358
+ for (const vertex of vertices) {
37359
+ const index = vertex.index + low * stride;
37360
+ if (index * nOut * bps < streamBytes.length * 8) next.push({ index, weight: vertex.weight * (1 - fraction) });
37361
+ if (fraction && (index + stride) * nOut * bps < streamBytes.length * 8) {
37362
+ next.push({ index: index + stride, weight: vertex.weight * fraction });
37363
+ }
37364
+ }
37365
+ vertices = next;
35059
37366
  stride *= size[i] ?? 2;
35060
37367
  }
35061
- const streamBytes = doc.decodeStream(resolved);
37368
+ const maxSample = 2 ** bps - 1;
37369
+ const readSample = (index) => {
37370
+ let bitOffset = index * bps, remaining = bps, value = 0;
37371
+ while (remaining > 0) {
37372
+ const bitInByte = bitOffset % 8;
37373
+ const take = Math.min(remaining, 8 - bitInByte);
37374
+ const byte = streamBytes[Math.floor(bitOffset / 8)] ?? 0;
37375
+ value = value * 2 ** take + (byte >> 8 - bitInByte - take & (1 << take) - 1);
37376
+ bitOffset += take;
37377
+ remaining -= take;
37378
+ }
37379
+ return value / maxSample;
37380
+ };
35062
37381
  const out2 = [];
35063
- const maxSample = bps === 16 ? 65535 : 255;
35064
37382
  for (let j = 0; j < nOut; j++) {
35065
- const sampleIdx = flatGridIndex * nOut + j;
35066
- let rawVal = 0;
35067
- if (bps === 16) {
35068
- rawVal = (streamBytes[sampleIdx * 2] ?? 0) << 8 | (streamBytes[sampleIdx * 2 + 1] ?? 0);
35069
- } else {
35070
- rawVal = streamBytes[sampleIdx] ?? 0;
35071
- }
35072
- const frac = rawVal / maxSample;
37383
+ let value = 0;
37384
+ for (const vertex of vertices) value += readSample(vertex.index * nOut + j) * vertex.weight;
35073
37385
  const dec0 = decode[j * 2] ?? 0;
35074
37386
  const dec1 = decode[j * 2 + 1] ?? 1;
35075
- out2.push(dec0 + frac * (dec1 - dec0));
37387
+ out2.push(dec0 + value * (dec1 - dec0));
35076
37388
  }
35077
37389
  return clampRange(out2);
35078
37390
  }
@@ -35082,34 +37394,40 @@ function evalShadingFunctionToComponents(doc, fnNode, inputs) {
35082
37394
  const d12 = dom[i * 2 + 1] ?? 1;
35083
37395
  return Math.max(d02, Math.min(d12, v));
35084
37396
  });
35085
- const tokens = tokenizePostScriptCode(doc.decodeStream(resolved));
35086
- const stackOut = evaluateType4PostScriptTokens(tokens, clampedInputs);
35087
- return clampRange(stackOut);
37397
+ const source = bytesToString3(doc.decodeStream(resolved));
37398
+ let cached = postScriptFunctions.get(resolved);
37399
+ if (!cached || cached.source !== source || cached.domain.length !== dom.length || cached.domain.some((value, index) => value !== dom[index]) || cached.range.length !== range.length || cached.range.some((value, index) => value !== range[index])) {
37400
+ cached = { source, domain: dom, range, evaluate: buildPostScriptJsFunction(source, dom, range) };
37401
+ postScriptFunctions.set(resolved, cached);
37402
+ }
37403
+ const output = [];
37404
+ cached.evaluate(clampedInputs, 0, output, 0);
37405
+ return output;
35088
37406
  }
35089
37407
  if (ft === 3) {
35090
37408
  const fnsArr = doc.resolveArray(dictGet(fnDict, "Functions"));
35091
37409
  const bounds = getNums("Bounds", []);
35092
37410
  const encode = getNums("Encode", []);
35093
37411
  if (fnsArr && fnsArr.items.length > 0) {
37412
+ const input = Math.max(dom[0] ?? 0, Math.min(dom[1] ?? 1, t));
35094
37413
  let segIdx = 0;
35095
- while (segIdx < bounds.length && t >= bounds[segIdx]) segIdx++;
37414
+ while (segIdx < bounds.length && input >= bounds[segIdx]) segIdx++;
35096
37415
  segIdx = Math.min(fnsArr.items.length - 1, segIdx);
35097
37416
  const b0 = segIdx === 0 ? dom[0] ?? 0 : bounds[segIdx - 1];
35098
37417
  const b1 = segIdx < bounds.length ? bounds[segIdx] : dom[1] ?? 1;
35099
37418
  const e0 = encode[segIdx * 2] ?? 0;
35100
37419
  const e1 = encode[segIdx * 2 + 1] ?? 1;
35101
- const localT = Math.abs(b1 - b0) > 1e-8 ? e0 + (t - b0) / (b1 - b0) * (e1 - e0) : e0;
35102
- return evalShadingFunctionToComponents(doc, fnsArr.items[segIdx], Math.max(0, Math.min(1, localT)));
37420
+ const localT = b1 !== b0 ? e0 + (input - b0) / (b1 - b0) * (e1 - e0) : e0;
37421
+ return clampRange(evalShadingFunctionToComponents(doc, fnsArr.items[segIdx], localT));
35103
37422
  }
35104
37423
  }
35105
- const c0 = getNums("C0", [0, 0, 0]);
35106
- const c1 = getNums("C1", [1, 1, 1]);
37424
+ const c0 = getNums("C0", [0]);
37425
+ const c1 = getNums("C1", [1]);
35107
37426
  const nNode = doc.resolve(dictGet(fnDict, "N"));
35108
- const expN = nNode?.kind === "number" && nNode.value > 0 ? nNode.value : 1;
37427
+ const expN = nNode?.kind === "number" ? nNode.value : 1;
35109
37428
  const d0 = dom[0] ?? 0;
35110
37429
  const d1 = dom[1] ?? 1;
35111
- const normT = Math.abs(d1 - d0) > 1e-8 ? (t - d0) / (d1 - d0) : t;
35112
- const w = Math.pow(Math.max(0, Math.min(1, normT)), expN);
37430
+ const w = Math.pow(Math.max(d0, Math.min(d1, t)), expN);
35113
37431
  const len = Math.max(c0.length, c1.length);
35114
37432
  const out = [];
35115
37433
  for (let i = 0; i < len; i++) {
@@ -35125,30 +37443,14 @@ function shadingComponentsToRgb(csName, comps) {
35125
37443
  return [v, v, v];
35126
37444
  }
35127
37445
  if (csName === "DeviceCMYK" || csName === "CMYK" || comps.length >= 4) {
35128
- const cc = comps[0] ?? 0, cm = comps[1] ?? 0, cy = comps[2] ?? 0, ck = comps[3] ?? 0;
35129
- return [(1 - cc) * (1 - ck), (1 - cm) * (1 - kClamp(ck)), (1 - cy) * (1 - kClamp(ck))];
37446
+ const rgb2 = cmykColorSpace2.getRgb([comps[0] ?? 0, comps[1] ?? 0, comps[2] ?? 0, comps[3] ?? 0], 0);
37447
+ return [rgb2[0] / 255, rgb2[1] / 255, rgb2[2] / 255];
35130
37448
  }
35131
37449
  return [comps[0] ?? 0, comps[1] ?? 0, comps[2] ?? 0];
35132
37450
  }
35133
37451
  function kClamp(v) {
35134
37452
  return Math.max(0, Math.min(1, v));
35135
37453
  }
35136
- function xyzToSrgb(X, Y, Z, Xw = 0.95047, Yw = 1, Zw = 1.08883) {
35137
- const scaleX = Xw > 1e-6 ? 0.95047 / Xw : 1;
35138
- const scaleY = Yw > 1e-6 ? 1 / Yw : 1;
35139
- const scaleZ = Zw > 1e-6 ? 1.08883 / Zw : 1;
35140
- const x = X * scaleX;
35141
- const y = Y * scaleY;
35142
- const z = Z * scaleZ;
35143
- const rl = 3.2404542 * x - 1.5371385 * y - 0.4985314 * z;
35144
- const gl = -0.969266 * x + 1.8760108 * y + 0.041556 * z;
35145
- const bl = 0.0556434 * x - 0.2040259 * y + 1.0572252 * z;
35146
- const toGamma = (u) => {
35147
- const c = Math.max(0, Math.min(1, u));
35148
- return c <= 31308e-7 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
35149
- };
35150
- return [toGamma(rl), toGamma(gl), toGamma(bl)];
35151
- }
35152
37454
  function getColorSpaceComponentCount(doc, csNode, activeResources, depth = 0) {
35153
37455
  if (!csNode || depth > 4) return 3;
35154
37456
  const resolved = doc ? doc.resolve(csNode) : csNode;
@@ -35205,63 +37507,10 @@ function convertColorSpaceComponentsToRgb(doc, csNode, csNameFallback, comps, ac
35205
37507
  if (resolved.kind === "array" && resolved.items.length > 0 && doc) {
35206
37508
  const familyNode = doc.resolve(resolved.items[0]);
35207
37509
  const family = familyNode?.kind === "name" ? familyNode.decoded : "";
35208
- if (family === "CalGray") {
35209
- const paramDict = resolved.items[1] ? doc.resolveDict(resolved.items[1]) : void 0;
35210
- const gNode = paramDict ? doc.resolve(dictGet(paramDict, "Gamma")) : void 0;
35211
- const gamma = gNode?.kind === "number" && gNode.value > 0 ? gNode.value : 1;
35212
- const a = Math.pow(kClamp(comps[0] ?? 0), gamma);
35213
- return [a, a, a];
35214
- }
35215
- if (family === "CalRGB") {
35216
- const paramDict = resolved.items[1] ? doc.resolveDict(resolved.items[1]) : void 0;
35217
- const gammaArr = paramDict ? doc.resolveArray(dictGet(paramDict, "Gamma")) : void 0;
35218
- const getArrNum = (arr, idx, fb) => {
35219
- const r = arr && arr.items[idx] ? doc.resolve(arr.items[idx]) : void 0;
35220
- return r?.kind === "number" ? r.value : fb;
35221
- };
35222
- const gr = getArrNum(gammaArr, 0, 1);
35223
- const gg = getArrNum(gammaArr, 1, 1);
35224
- const gb = getArrNum(gammaArr, 2, 1);
35225
- const ag = Math.pow(kClamp(comps[0] ?? 0), gr > 0 ? gr : 1);
35226
- const bg = Math.pow(kClamp(comps[1] ?? 0), gg > 0 ? gg : 1);
35227
- const cg = Math.pow(kClamp(comps[2] ?? 0), gb > 0 ? gb : 1);
35228
- const matArr = paramDict ? doc.resolveArray(dictGet(paramDict, "Matrix")) : void 0;
35229
- if (matArr && matArr.items.length >= 9) {
35230
- const m = (i) => getArrNum(matArr, i, 0);
35231
- const X = m(0) * ag + m(3) * bg + m(6) * cg;
35232
- const Y = m(1) * ag + m(4) * bg + m(7) * cg;
35233
- const Z = m(2) * ag + m(5) * bg + m(8) * cg;
35234
- const wpArr = paramDict ? doc.resolveArray(dictGet(paramDict, "WhitePoint")) : void 0;
35235
- const Xw = getArrNum(wpArr, 0, 0.95047);
35236
- const Yw = getArrNum(wpArr, 1, 1);
35237
- const Zw = getArrNum(wpArr, 2, 1.08883);
35238
- return xyzToSrgb(X, Y, Z, Xw, Yw, Zw);
35239
- }
35240
- return [ag, bg, cg];
35241
- }
35242
- if (family === "Lab") {
35243
- const paramDict = resolved.items[1] ? doc.resolveDict(resolved.items[1]) : void 0;
35244
- const wpArr = paramDict ? doc.resolveArray(dictGet(paramDict, "WhitePoint")) : void 0;
35245
- const rangeArr = paramDict ? doc.resolveArray(dictGet(paramDict, "Range")) : void 0;
35246
- const getNum = (arr, idx, fb) => {
35247
- const r = arr && arr.items[idx] ? doc.resolve(arr.items[idx]) : void 0;
35248
- return r?.kind === "number" ? r.value : fb;
35249
- };
35250
- const Xw = getNum(wpArr, 0, 0.95047);
35251
- const Yw = getNum(wpArr, 1, 1);
35252
- const Zw = getNum(wpArr, 2, 1.08883);
35253
- const amin = getNum(rangeArr, 0, -100);
35254
- const amax = getNum(rangeArr, 1, 100);
35255
- const bmin = getNum(rangeArr, 2, -100);
35256
- const bmax = getNum(rangeArr, 3, 100);
35257
- const Lstar = Math.max(0, Math.min(100, comps[0] ?? 0));
35258
- const astar = Math.max(amin, Math.min(amax, comps[1] ?? 0));
35259
- const bstar = Math.max(bmin, Math.min(bmax, comps[2] ?? 0));
35260
- const M = (Lstar + 16) / 116;
35261
- const L = M + astar / 500;
35262
- const N = M - bstar / 200;
35263
- const gFn = (x) => x >= 6 / 29 ? x * x * x : 108 / 841 * (x - 4 / 29);
35264
- return xyzToSrgb(Xw * gFn(L), Yw * gFn(M), Zw * gFn(N), Xw, Yw, Zw);
37510
+ if (family === "CalGray" || family === "CalRGB" || family === "Lab") {
37511
+ const colorSpace = createCalibratedColorSpace(doc, family, resolved.items[1]);
37512
+ const rgb2 = colorSpace.getRgb(comps, 0);
37513
+ return [rgb2[0] / 255, rgb2[1] / 255, rgb2[2] / 255];
35265
37514
  }
35266
37515
  if (family === "ICCBased" && resolved.items[1]) {
35267
37516
  const iccNode = doc.resolve(resolved.items[1]);
@@ -35912,7 +38161,8 @@ function evaluateContentStreamToDisplayList(params) {
35912
38161
  const shDict = shNode?.kind === "dict" ? shNode : shNode?.kind === "stream" ? shNode.dict : void 0;
35913
38162
  const shStream = shNode?.kind === "stream" ? shNode : void 0;
35914
38163
  if (shDict) {
35915
- const targetBox = st.clipRect ?? [0, 0, params.width, params.height];
38164
+ const [originX, originY] = params.origin ?? [0, 0];
38165
+ const targetBox = st.clipRect ?? [originX, originY, originX + params.width, originY + params.height];
35916
38166
  const img = renderShadingDictToImage(
35917
38167
  params.cosDoc,
35918
38168
  shDict,
@@ -35951,12 +38201,10 @@ function evaluateContentStreamToDisplayList(params) {
35951
38201
  } else if (operator === "RG" || operator === "SC" || operator === "SCN") {
35952
38202
  st.strokeColor = resolveScColorOperands(operator === "RG" ? "DeviceRGB" : st.strokeColorSpaceName, ops, activeResources);
35953
38203
  } else if (operator === "k") {
35954
- const c = num(0), m = num(1), y = num(2), k = num(3);
35955
- st.fillColor = { r: (1 - c) * (1 - k), g: (1 - m) * (1 - k), b: (1 - y) * (1 - k) };
38204
+ st.fillColor = resolveScColorOperands("DeviceCMYK", ops, activeResources);
35956
38205
  st.fillPatternName = void 0;
35957
38206
  } else if (operator === "K") {
35958
- const c = num(0), m = num(1), y = num(2), k = num(3);
35959
- st.strokeColor = { r: (1 - c) * (1 - k), g: (1 - m) * (1 - k), b: (1 - y) * (1 - k) };
38207
+ st.strokeColor = resolveScColorOperands("DeviceCMYK", ops, activeResources);
35960
38208
  } else if (operator === "gs" && params.cosDoc && activeResources && ops[0]?.kind === "name") {
35961
38209
  const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
35962
38210
  const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
@@ -36165,7 +38413,7 @@ function evaluateContentStreamToDisplayList(params) {
36165
38413
  stateStack.pop();
36166
38414
  capturedOperations = parentOperations;
36167
38415
  }
36168
- if (compositeGroup) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
38416
+ if (compositeGroup) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, isolated, bboxClip: nextClipPaths?.[0], blendMode: st.blendMode, clipRect: st.clipRect } });
36169
38417
  };
36170
38418
  const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
36171
38419
  for (const node of nodes) {
@@ -36749,6 +38997,7 @@ function evaluateContentStreamToDisplayList(params) {
36749
38997
  pageIndex: params.pageIndex,
36750
38998
  width: params.width,
36751
38999
  height: params.height,
39000
+ ...params.origin ? { origin: params.origin } : {},
36752
39001
  rotation: params.rotation ?? 0,
36753
39002
  glyphs,
36754
39003
  paths,
@@ -38219,7 +40468,7 @@ var PdfPage = class {
38219
40468
  return [n0.value, n1.value, n2.value, n3.value];
38220
40469
  }
38221
40470
  }
38222
- return [0, 0, 612, 792];
40471
+ return key === "MediaBox" ? [0, 0, 612, 792] : this.resolveBox("MediaBox");
38223
40472
  }
38224
40473
  getMediaBox() {
38225
40474
  return this.resolveBox("MediaBox");
@@ -38892,16 +41141,19 @@ var PdfPage = class {
38892
41141
  });
38893
41142
  }
38894
41143
  }
38895
- return evaluateContentStreamToDisplayList({
41144
+ const mediaBox = this.getMediaBox(), cropBox = this.getCropBox();
41145
+ const originX = Math.min(mediaBox[0], mediaBox[2]), originY = Math.min(mediaBox[1], mediaBox[3]);
41146
+ return { ...evaluateContentStreamToDisplayList({
38896
41147
  pageIndex: this.index,
38897
41148
  width,
38898
41149
  height,
41150
+ origin: [originX, originY],
38899
41151
  rotation: this.getRotation(),
38900
41152
  nodes: baseNodes,
38901
41153
  cosDoc: this.cosDoc,
38902
41154
  resourcesDict: evalResourcesDict,
38903
41155
  annotations: extractPageAnnotations(this.cosDoc, this.pageDict)
38904
- });
41156
+ }), cropBox: [cropBox[0] - originX, cropBox[1] - originY, cropBox[2] - originX, cropBox[3] - originY] };
38905
41157
  }
38906
41158
  extractPage(options) {
38907
41159
  const dl = this.evaluateDisplayList();
@@ -38919,10 +41171,10 @@ var PdfPage = class {
38919
41171
  return extractTablesFromDisplayList(this.evaluateDisplayList());
38920
41172
  }
38921
41173
  renderToBitmap(options) {
38922
- return renderDisplayListToBitmap(this.evaluateDisplayList(), options);
41174
+ return renderDisplayListToBitmap(this.evaluateDisplayList({ hideAnnotations: options?.hideAnnotations }), options);
38923
41175
  }
38924
41176
  renderToPng(options) {
38925
- return renderDisplayListToPng(this.evaluateDisplayList(), options);
41177
+ return renderDisplayListToPng(this.evaluateDisplayList({ hideAnnotations: options?.hideAnnotations }), options);
38926
41178
  }
38927
41179
  };
38928
41180
  function createStandardFontHandle(standardName) {
@@ -40368,7 +42620,7 @@ function prepareStroke(path, scale) {
40368
42620
  }
40369
42621
  return { matrix, width, dashArray, dashPhase };
40370
42622
  }
40371
- function strokeContours(path, pageHeight, scale) {
42623
+ function strokeContours(path, pageHeight, scale, originX = 0, originY = 0) {
40372
42624
  const stroke = prepareStroke(path, scale);
40373
42625
  if (!stroke) return [];
40374
42626
  const inverse = inverseStrokeMatrix(stroke.matrix);
@@ -40380,8 +42632,8 @@ function strokeContours(path, pageHeight, scale) {
40380
42632
  (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
40381
42633
  ];
40382
42634
  const toScreen = ([x, y]) => [
40383
- (a * x / strokeScale + c * y / strokeScale + e) * scale,
40384
- (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
42635
+ (a * x / strokeScale + c * y / strokeScale + e - originX) * scale,
42636
+ (pageHeight + originY - b * x / strokeScale - d * y / strokeScale - f) * scale
40385
42637
  ];
40386
42638
  const contours = strokeOutlines(
40387
42639
  segmentsToScreenPaths(path.segments, pageHeight, scale, project),
@@ -40539,18 +42791,37 @@ function renderSoftMask(mask, displayList, scale) {
40539
42791
  }
40540
42792
  return bitmap;
40541
42793
  }
40542
- function hasBlendModes(operations) {
40543
- return operations.some((operation) => !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasBlendModes(operation.value.operations));
42794
+ function getDisplayListCropBox(list) {
42795
+ const full = [0, 0, list.width, list.height];
42796
+ const box = list.cropBox;
42797
+ if (!box || !box.every(Number.isFinite)) return full;
42798
+ const x0 = Math.max(0, Math.min(box[0], box[2]));
42799
+ const y0 = Math.max(0, Math.min(box[1], box[3]));
42800
+ const x1 = Math.min(list.width, Math.max(box[0], box[2]));
42801
+ const y1 = Math.min(list.height, Math.max(box[1], box[3]));
42802
+ return x1 > x0 && y1 > y0 ? [x0, y0, x1, y1] : full;
42803
+ }
42804
+ function hasCompositingEffects(operations, includeSoftMasks = false) {
42805
+ return operations.some((operation) => includeSoftMasks && !!operation.value.softMask || !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasCompositingEffects(operation.value.operations, includeSoftMasks));
42806
+ }
42807
+ function needsGroupBackdrop(group) {
42808
+ return group.isolated === false && !!group.softMask && hasCompositingEffects(group.operations, true);
42809
+ }
42810
+ function containsBackdropGroup(operations) {
42811
+ return operations.some((operation) => operation.kind === "group" && (needsGroupBackdrop(operation.value) || containsBackdropGroup(operation.value.operations)));
40544
42812
  }
40545
42813
  function renderDisplayListToBitmap(displayList, options = {}) {
40546
42814
  const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
40547
42815
  const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
40548
42816
  const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
40549
42817
  const scale = scaleX;
42818
+ const [originX, originY] = displayList.origin ?? [0, 0];
42819
+ const pageTop = originY + displayList.height;
42820
+ const toScreen = (x, y) => [(x - originX) * scale, (pageTop - y) * scale];
40550
42821
  const width = Math.max(1, Math.round(displayList.width * scale));
40551
42822
  const height = Math.max(1, Math.round(displayList.height * scale));
40552
42823
  const rgba = new Uint8Array(width * height * 4);
40553
- const deferBackground = !options.transparent && hasBlendModes(paintOperations(displayList));
42824
+ const deferBackground = !options.transparent && hasCompositingEffects(paintOperations(displayList));
40554
42825
  const transparent = options.transparent || deferBackground;
40555
42826
  const bg = options.background ?? { r: 1, g: 1, b: 1 };
40556
42827
  const bgR = transparent ? 0 : Math.round(bg.r * 255);
@@ -40575,14 +42846,27 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40575
42846
  let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
40576
42847
  if (operation.kind === "group") {
40577
42848
  const group = operation.value;
40578
- const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
42849
+ let operations = group.operations;
42850
+ if (needsGroupBackdrop(group)) {
42851
+ operations = [{ kind: "image", value: {
42852
+ name: "GroupBackdrop",
42853
+ width,
42854
+ height,
42855
+ decodedRgba: rgba.slice(),
42856
+ matrix: [width / scale, 0, 0, height / scale, originX, pageTop - height / scale],
42857
+ colorSpace: "DeviceRGB",
42858
+ bitsPerComponent: 8,
42859
+ ...group.bboxClip ? { clipPaths: [group.bboxClip] } : {}
42860
+ } }, ...operations];
42861
+ }
42862
+ const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, useCropBox: false, transparent: true });
40579
42863
  for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
40580
42864
  operation = { kind: "image", value: {
40581
42865
  name: "TransparencyGroup",
40582
42866
  width: bitmap.width,
40583
42867
  height: bitmap.height,
40584
42868
  decodedRgba: bitmap.data,
40585
- matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
42869
+ matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, originX, pageTop - bitmap.height / scale],
40586
42870
  colorSpace: "DeviceRGB",
40587
42871
  bitsPerComponent: 8,
40588
42872
  blendMode: group.blendMode,
@@ -40596,7 +42880,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40596
42880
  for (const clip of clips) {
40597
42881
  const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
40598
42882
  const layer = new Uint8Array(width * height * 4);
40599
- fillEdgesScanline4x4(layer, width, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
42883
+ fillEdgesScanline4x4(layer, width, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale, toScreen), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
40600
42884
  for (let i = 3; i < layer.length; i += 4) clipMask[i] = Math.round(clipMask[i] * layer[i] / 255);
40601
42885
  }
40602
42886
  cachedClips = clips;
@@ -40643,15 +42927,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40643
42927
  if (operation.kind === "path") {
40644
42928
  const path = operation.value;
40645
42929
  if (path.fillColor) {
40646
- const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale), true);
40647
- const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
42930
+ const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale, toScreen), true);
42931
+ const clipScreen = path.clipRect ? [(path.clipRect[0] - originX) * scale, (pageTop - path.clipRect[3]) * scale, (path.clipRect[2] - originX) * scale, (pageTop - path.clipRect[1]) * scale] : void 0;
40648
42932
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40649
42933
  }
40650
42934
  if (path.strokeColor) {
40651
42935
  const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40652
42936
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
40653
- const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
40654
- const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
42937
+ const edges = pathsToEdges(strokeContours(path, displayList.height, scale, originX, originY).map((points) => ({ points, closed: true })));
42938
+ const clipScreen = path.clipRect ? [(path.clipRect[0] - originX) * scale, (pageTop - path.clipRect[3]) * scale, (path.clipRect[2] - originX) * scale, (pageTop - path.clipRect[1]) * scale] : void 0;
40655
42939
  fillEdgesScanline4x4(
40656
42940
  rgba,
40657
42941
  width,
@@ -40674,12 +42958,12 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40674
42958
  if (Math.abs(det) <= 1e-8) continue;
40675
42959
  const cornersPdfX = [e, a + e, a + c + e, c + e];
40676
42960
  const cornersPdfY = [f, b + f, b + d + f, d + f];
40677
- const cornersPx = cornersPdfX.map((cx) => cx * scale);
40678
- const cornersPy = cornersPdfY.map((cy) => (displayList.height - cy) * scale);
40679
- const clipMinPx = img.clipRect ? Math.floor(img.clipRect[0] * scale) : 0;
40680
- const clipMaxPx = img.clipRect ? Math.ceil(img.clipRect[2] * scale) - 1 : width - 1;
40681
- const clipMinPy = img.clipRect ? Math.floor((displayList.height - img.clipRect[3]) * scale) : 0;
40682
- const clipMaxPy = img.clipRect ? Math.ceil((displayList.height - img.clipRect[1]) * scale) - 1 : height - 1;
42961
+ const cornersPx = cornersPdfX.map((cx) => (cx - originX) * scale);
42962
+ const cornersPy = cornersPdfY.map((cy) => (pageTop - cy) * scale);
42963
+ const clipMinPx = img.clipRect ? Math.floor((img.clipRect[0] - originX) * scale) : 0;
42964
+ const clipMaxPx = img.clipRect ? Math.ceil((img.clipRect[2] - originX) * scale) - 1 : width - 1;
42965
+ const clipMinPy = img.clipRect ? Math.floor((pageTop - img.clipRect[3]) * scale) : 0;
42966
+ const clipMaxPy = img.clipRect ? Math.ceil((pageTop - img.clipRect[1]) * scale) - 1 : height - 1;
40683
42967
  const minPx = Math.max(0, clipMinPx, Math.floor(Math.min(...cornersPx)));
40684
42968
  const maxPx = Math.min(width - 1, clipMaxPx, Math.ceil(Math.max(...cornersPx)) - 1);
40685
42969
  const minPy = Math.max(0, clipMinPy, Math.floor(Math.min(...cornersPy)));
@@ -40696,11 +42980,11 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40696
42980
  const smooth = Math.fround((s1 + s2 + Math.hypot(s1 - s2, 2 * cross)) / 2) <= 1;
40697
42981
  const sample = new Float64Array(4);
40698
42982
  for (let py = minPy; py <= maxPy; py++) {
40699
- const yPdf = displayList.height - (py + 0.5) / scale;
42983
+ const yPdf = pageTop - (py + 0.5) / scale;
40700
42984
  if (img.clipRect && (yPdf < img.clipRect[1] || yPdf > img.clipRect[3])) continue;
40701
42985
  const dyPdf = yPdf - f;
40702
42986
  for (let px = minPx; px <= maxPx; px++) {
40703
- const xPdf = (px + 0.5) / scale;
42987
+ const xPdf = originX + (px + 0.5) / scale;
40704
42988
  if (img.clipRect && (xPdf < img.clipRect[0] || xPdf > img.clipRect[2])) continue;
40705
42989
  const dxPdf = xPdf - e;
40706
42990
  const u = (d * dxPdf - c * dyPdf) / det;
@@ -40761,6 +43045,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40761
43045
  }
40762
43046
  result = { width: targetW, height: targetH, data: resampled };
40763
43047
  }
43048
+ if (options.useCropBox) {
43049
+ const box = getDisplayListCropBox(displayList);
43050
+ result = cropRgbaBitmap(result, {
43051
+ x: box[0] * scaleX,
43052
+ y: (displayList.height - box[3]) * scaleY,
43053
+ width: (box[2] - box[0]) * scaleX,
43054
+ height: (box[3] - box[1]) * scaleY
43055
+ });
43056
+ }
40764
43057
  result = rotateRgbaBitmapQuarterTurns(result, displayList.rotation ?? 0);
40765
43058
  if (options.cropRect) {
40766
43059
  result = cropRgbaBitmap(result, options.cropRect);
@@ -40830,18 +43123,44 @@ function svgPathData(segments, height, matrix) {
40830
43123
  }
40831
43124
  function renderDisplayListToSvg(displayList, options = {}) {
40832
43125
  const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1);
43126
+ if (containsBackdropGroup(paintOperations(displayList))) {
43127
+ const bitmap = renderDisplayListToBitmap(displayList, { ...options, scale: baseScale });
43128
+ const embedded = svgImage({
43129
+ name: "PageComposite",
43130
+ width: bitmap.width,
43131
+ height: bitmap.height,
43132
+ decodedRgba: bitmap.data,
43133
+ matrix: [bitmap.width, 0, 0, bitmap.height, 0, 0],
43134
+ colorSpace: "DeviceRGB",
43135
+ bitsPerComponent: 8
43136
+ }, bitmap.height);
43137
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${bitmap.width}" height="${bitmap.height}" viewBox="0 0 ${bitmap.width} ${bitmap.height}">${embedded}</svg>
43138
+ `;
43139
+ }
40833
43140
  const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
40834
43141
  const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
40835
- const viewport = new PageViewport({ viewBox: [0, 0, displayList.width, displayList.height], userUnit: 1, scale: 1, rotation: displayList.rotation ?? 0 });
43142
+ const [originX, originY] = displayList.origin ?? [0, 0];
43143
+ const viewport = new PageViewport({ viewBox: [originX, originY, originX + displayList.width, originY + displayList.height], userUnit: 1, scale: 1, rotation: displayList.rotation ?? 0 });
40836
43144
  const quarterTurn = displayList.rotation === 90 || displayList.rotation === 270;
40837
43145
  const outputScaleX = quarterTurn ? scaleY : scaleX;
40838
43146
  const outputScaleY = quarterTurn ? scaleX : scaleY;
40839
- const fullW = Math.max(1, Math.round(viewport.width * outputScaleX));
40840
- const fullH = Math.max(1, Math.round(viewport.height * outputScaleY));
40841
- const vbX = options.cropRect ? options.cropRect.x / outputScaleX : 0;
40842
- const vbY = options.cropRect ? options.cropRect.y / outputScaleY : 0;
40843
- const vbW = options.cropRect && options.cropRect.width > 0 ? options.cropRect.width / outputScaleX : Math.max(1, viewport.width - vbX);
40844
- const vbH = options.cropRect && options.cropRect.height > 0 ? options.cropRect.height / outputScaleY : Math.max(1, viewport.height - vbY);
43147
+ let bounds = [0, 0, viewport.width, viewport.height];
43148
+ if (options.useCropBox) {
43149
+ const box = getDisplayListCropBox(displayList);
43150
+ const [x0, y0, x1, y1] = [box[0] + originX, box[1] + originY, box[2] + originX, box[3] + originY];
43151
+ const [a, b, c, d, e, f] = viewport.transform;
43152
+ bounds = [a * x0 + c * y0 + e, b * x0 + d * y0 + f, a * x1 + c * y1 + e, b * x1 + d * y1 + f];
43153
+ }
43154
+ const viewX = Math.min(bounds[0], bounds[2]), viewY = Math.min(bounds[1], bounds[3]);
43155
+ const viewWidth = Math.abs(bounds[2] - bounds[0]), viewHeight = Math.abs(bounds[3] - bounds[1]);
43156
+ const fullW = Math.max(1, Math.round(viewWidth * outputScaleX));
43157
+ const fullH = Math.max(1, Math.round(viewHeight * outputScaleY));
43158
+ const cropX = options.cropRect ? options.cropRect.x / outputScaleX : 0;
43159
+ const vbX = viewX + cropX;
43160
+ const cropY = options.cropRect ? options.cropRect.y / outputScaleY : 0;
43161
+ const vbY = viewY + cropY;
43162
+ const vbW = options.cropRect && options.cropRect.width > 0 ? options.cropRect.width / outputScaleX : Math.max(1, viewWidth - cropX);
43163
+ const vbH = options.cropRect && options.cropRect.height > 0 ? options.cropRect.height / outputScaleY : Math.max(1, viewHeight - cropY);
40845
43164
  const outW = options.cropRect && options.cropRect.width > 0 ? Math.round(options.cropRect.width) : Math.max(1, fullW - Math.round(options.cropRect?.x ?? 0));
40846
43165
  const outH = options.cropRect && options.cropRect.height > 0 ? Math.round(options.cropRect.height) : Math.max(1, fullH - Math.round(options.cropRect?.y ?? 0));
40847
43166
  const parts = [
@@ -40851,7 +43170,7 @@ function renderDisplayListToSvg(displayList, options = {}) {
40851
43170
  parts.push(` <rect x="${vbX}" y="${vbY}" width="${vbW}" height="${vbH}" fill="#ffffff"/>`);
40852
43171
  }
40853
43172
  parts.push('<g style="isolation:isolate">');
40854
- if (displayList.rotation) {
43173
+ if (displayList.rotation || originX || originY) {
40855
43174
  const [a, b, c, d, e, f] = viewport.transform;
40856
43175
  parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
40857
43176
  }
@@ -40877,11 +43196,11 @@ function renderDisplayListToSvg(displayList, options = {}) {
40877
43196
  width: bitmap.width,
40878
43197
  height: bitmap.height,
40879
43198
  decodedRgba: bitmap.data,
40880
- matrix: [displayList.width, 0, 0, displayList.height, 0, 0],
43199
+ matrix: [displayList.width, 0, 0, displayList.height, originX, originY],
40881
43200
  colorSpace: "DeviceGray",
40882
43201
  bitsPerComponent: 8
40883
43202
  };
40884
- 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>`);
43203
+ parts.push(`<defs><mask id="${id}" maskUnits="userSpaceOnUse" x="${originX}" y="${-originY}" width="${displayList.width}" height="${displayList.height}" style="mask-type:alpha">${svgImage(image, displayList.height)}</mask></defs>`);
40885
43204
  }
40886
43205
  parts.push(`<g mask="url(#${id})">`);
40887
43206
  }
@@ -40893,7 +43212,7 @@ function renderDisplayListToSvg(displayList, options = {}) {
40893
43212
  }
40894
43213
  for (const image of imageClips) {
40895
43214
  const id = `image-clip-${clipId++}`;
40896
- 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})">`);
43215
+ parts.push(`<defs><mask id="${id}" maskUnits="userSpaceOnUse" x="${originX}" y="${-originY}" width="${displayList.width}" height="${displayList.height}" style="mask-type:alpha">${svgImage(image, displayList.height)}</mask></defs><g mask="url(#${id})">`);
40897
43216
  }
40898
43217
  if (operation.kind === "group") {
40899
43218
  parts.push(`<g opacity="${operation.value.alpha}" style="isolation:isolate">`);
@@ -40937,84 +43256,11 @@ function renderDisplayListToSvg(displayList, options = {}) {
40937
43256
  }
40938
43257
  };
40939
43258
  appendOperations(paintOperations(displayList));
40940
- if (displayList.rotation) parts.push("</g>");
43259
+ if (displayList.rotation || originX || originY) parts.push("</g>");
40941
43260
  parts.push("</g>");
40942
43261
  parts.push("</svg>\n");
40943
43262
  return parts.join("\n");
40944
43263
  }
40945
- function collectLeavesForRaster(cosDoc, node, out = [], visited = /* @__PURE__ */ new Set()) {
40946
- if (!node) return out;
40947
- let ref;
40948
- if (node.kind === "ref") {
40949
- if (visited.has(node.objectNumber)) return out;
40950
- visited.add(node.objectNumber);
40951
- ref = node;
40952
- }
40953
- const dict = cosDoc.resolveDict(node);
40954
- if (!dict) return out;
40955
- const kids = cosDoc.resolveArray(dictGet(dict, "Kids"));
40956
- if (kids) {
40957
- for (const k of kids.items) collectLeavesForRaster(cosDoc, k, out, visited);
40958
- } else {
40959
- out.push({ ref: ref ?? cosDoc.allocateObject(dict), dict });
40960
- }
40961
- return out;
40962
- }
40963
- function extractBoxArray(cosDoc, dict, key) {
40964
- let cur = dict;
40965
- const visited = /* @__PURE__ */ new Set();
40966
- while (cur && !visited.has(cur)) {
40967
- visited.add(cur);
40968
- const arr = cosDoc.resolveArray(dictGet(cur, key));
40969
- if (arr && arr.items.length >= 4) {
40970
- const nums = arr.items.slice(0, 4).map((item) => {
40971
- const r = cosDoc.resolve(item);
40972
- return r?.kind === "number" ? r.value : 0;
40973
- });
40974
- return [nums[0], nums[1], nums[2], nums[3]];
40975
- }
40976
- cur = cosDoc.resolveDict(dictGet(cur, "Parent"));
40977
- }
40978
- return void 0;
40979
- }
40980
- function renderPdfPageToBitmap(pdfBytes, pageIndex = 0, options) {
40981
- const cos = pdfBytes instanceof Uint8Array ? parseCosDocument(pdfBytes) : pdfBytes;
40982
- const catalog = cos.resolveDict(cos.rootRef);
40983
- const leaves = collectLeavesForRaster(cos, catalog ? dictGet(catalog, "Pages") : void 0);
40984
- const leaf = leaves[pageIndex] ?? (pageIndex >= 1 ? leaves[pageIndex - 1] : void 0);
40985
- if (!leaf) throw new Error(`Page index ${pageIndex} out of bounds`);
40986
- const resolvedIndex = leaves.indexOf(leaf);
40987
- const page = new PdfPage(cos, leaf.ref, leaf.dict, resolvedIndex);
40988
- const { cropRect, ...restOptions } = options ?? {};
40989
- let bitmap = renderDisplayListToBitmap(
40990
- // CropBox is in unrotated page coordinates. Apply page rotation after it.
40991
- { ...page.evaluateDisplayList({ hideAnnotations: options?.hideAnnotations }), rotation: 0 },
40992
- restOptions
40993
- );
40994
- if (options?.useCropBox) {
40995
- const cropBox = extractBoxArray(cos, leaf.dict, "CropBox");
40996
- if (cropBox) {
40997
- const mediaBox = extractBoxArray(cos, leaf.dict, "MediaBox") ?? [0, 0, page.getSize().width, page.getSize().height];
40998
- const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
40999
- const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
41000
- const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
41001
- const mediaH = mediaBox[3] - mediaBox[1];
41002
- const bx = Math.round((cropBox[0] - mediaBox[0]) * scaleX);
41003
- const by = Math.round((mediaH - (cropBox[3] - mediaBox[1])) * scaleY);
41004
- const bw = Math.max(1, Math.round(Math.abs(cropBox[2] - cropBox[0]) * scaleX));
41005
- const bh = Math.max(1, Math.round(Math.abs(cropBox[3] - cropBox[1]) * scaleY));
41006
- bitmap = cropRgbaBitmap(bitmap, { x: bx, y: by, width: bw, height: bh });
41007
- }
41008
- }
41009
- const rotation = page.getRotation();
41010
- if (rotation === 90 || rotation === 180 || rotation === 270) {
41011
- bitmap = rotateRgbaBitmapQuarterTurns(bitmap, rotation);
41012
- }
41013
- if (cropRect) {
41014
- bitmap = cropRgbaBitmap(bitmap, cropRect);
41015
- }
41016
- return bitmap;
41017
- }
41018
43264
  function discardUnreachableObjects(doc) {
41019
43265
  const reachable = /* @__PURE__ */ new Set();
41020
43266
  const visited = /* @__PURE__ */ new Set();
@@ -41925,29 +44171,9 @@ function runPdftoppmCliSync(argv, files, options = {}) {
41925
44171
  if (oddOnly && p % 2 === 0) continue;
41926
44172
  if (evenOnly && p % 2 === 1) continue;
41927
44173
  const page = doc.getPage(p - 1);
41928
- let rawSize = page.getSize();
41929
- let resolvedCropBox;
41930
- if (useCropBox) {
41931
- let cur = page.pageDict;
41932
- const visited = /* @__PURE__ */ new Set();
41933
- while (cur && !visited.has(cur)) {
41934
- visited.add(cur);
41935
- const cb = doc.cos.resolveArray(dictGet(cur, "CropBox"));
41936
- if (cb && cb.items.length >= 4) {
41937
- const nums = cb.items.slice(0, 4).map((it) => {
41938
- const r = doc.cos.resolve(it);
41939
- return r?.kind === "number" ? r.value : 0;
41940
- });
41941
- resolvedCropBox = [nums[0], nums[1], nums[2], nums[3]];
41942
- rawSize = {
41943
- width: Math.max(1, Math.abs(nums[2] - nums[0])),
41944
- height: Math.max(1, Math.abs(nums[3] - nums[1]))
41945
- };
41946
- break;
41947
- }
41948
- cur = doc.cos.resolveDict(dictGet(cur, "Parent"));
41949
- }
41950
- }
44174
+ const displayList = page.evaluateDisplayList({ hideAnnotations });
44175
+ const box = useCropBox ? getDisplayListCropBox(displayList) : [0, 0, displayList.width, displayList.height];
44176
+ const rawSize = { width: box[2] - box[0], height: box[3] - box[1] };
41951
44177
  const rot = page.getRotation();
41952
44178
  const ptW = rot === 90 || rot === 270 ? rawSize.height : rawSize.width;
41953
44179
  const ptH = rot === 90 || rot === 270 ? rawSize.width : rawSize.height;
@@ -41970,33 +44196,17 @@ function runPdftoppmCliSync(argv, files, options = {}) {
41970
44196
  const cropRect = hasCrop ? { x: cropX, y: cropY, width: cropW, height: cropH } : void 0;
41971
44197
  let renderedBytes;
41972
44198
  if (format === "svg") {
41973
- let svgCropRect = cropRect;
41974
- if (useCropBox && resolvedCropBox) {
41975
- const fullMediaSize = page.getSize();
41976
- const scaleX = effDpiX / 72;
41977
- const scaleY = effDpiY / 72;
41978
- const cbScreenX = resolvedCropBox[0] * scaleX;
41979
- const cbScreenY = (fullMediaSize.height - resolvedCropBox[3]) * scaleY;
41980
- const cbScreenW = Math.abs(resolvedCropBox[2] - resolvedCropBox[0]) * scaleX;
41981
- const cbScreenH = Math.abs(resolvedCropBox[3] - resolvedCropBox[1]) * scaleY;
41982
- svgCropRect = hasCrop ? {
41983
- x: cbScreenX + cropX,
41984
- y: cbScreenY + cropY,
41985
- width: cropW || Math.max(1, cbScreenW - cropX),
41986
- height: cropH || Math.max(1, cbScreenH - cropY)
41987
- } : { x: cbScreenX, y: cbScreenY, width: cbScreenW, height: cbScreenH };
41988
- }
41989
- const svgText = renderDisplayListToSvg(page.evaluateDisplayList({ hideAnnotations }), {
44199
+ const svgText = renderDisplayListToSvg(displayList, {
41990
44200
  dpiX: effDpiX,
41991
44201
  dpiY: effDpiY,
41992
44202
  useCropBox,
41993
- cropRect: svgCropRect,
44203
+ cropRect,
41994
44204
  hideAnnotations,
41995
44205
  transparent
41996
44206
  });
41997
44207
  renderedBytes = new TextEncoder().encode(svgText);
41998
44208
  } else {
41999
- const bitmap = renderPdfPageToBitmap(doc.cos, p - 1, {
44209
+ const bitmap = renderDisplayListToBitmap(displayList, {
42000
44210
  dpiX: effDpiX,
42001
44211
  dpiY: effDpiY,
42002
44212
  useCropBox,