@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
@@ -13652,16 +13652,16 @@ var require_JpegEmbedder = __commonJS({
13652
13652
  65486,
13653
13653
  65487
13654
13654
  ];
13655
- var ColorSpace;
13656
- (function(ColorSpace2) {
13657
- ColorSpace2["DeviceGray"] = "DeviceGray";
13658
- ColorSpace2["DeviceRGB"] = "DeviceRGB";
13659
- ColorSpace2["DeviceCMYK"] = "DeviceCMYK";
13660
- })(ColorSpace || (ColorSpace = {}));
13655
+ var ColorSpace2;
13656
+ (function(ColorSpace3) {
13657
+ ColorSpace3["DeviceGray"] = "DeviceGray";
13658
+ ColorSpace3["DeviceRGB"] = "DeviceRGB";
13659
+ ColorSpace3["DeviceCMYK"] = "DeviceCMYK";
13660
+ })(ColorSpace2 || (ColorSpace2 = {}));
13661
13661
  var ChannelToColorSpace = {
13662
- 1: ColorSpace.DeviceGray,
13663
- 3: ColorSpace.DeviceRGB,
13664
- 4: ColorSpace.DeviceCMYK
13662
+ 1: ColorSpace2.DeviceGray,
13663
+ 3: ColorSpace2.DeviceRGB,
13664
+ 4: ColorSpace2.DeviceCMYK
13665
13665
  };
13666
13666
  var JpegEmbedder = (
13667
13667
  /** @class */
@@ -13726,7 +13726,7 @@ var require_JpegEmbedder = __commonJS({
13726
13726
  //
13727
13727
  // Applying a swap here as a hedge that most bytes passing
13728
13728
  // through this method will benefit from it.
13729
- Decode: this.colorSpace === ColorSpace.DeviceCMYK ? [1, 0, 1, 0, 1, 0, 1, 0] : void 0
13729
+ Decode: this.colorSpace === ColorSpace2.DeviceCMYK ? [1, 0, 1, 0, 1, 0, 1, 0] : void 0
13730
13730
  });
13731
13731
  if (ref) {
13732
13732
  context.assign(ref, xObject);
@@ -196016,6 +196016,2614 @@ var getFontBasicMetrics = getLookupTableFactory(function(t) {
196016
196016
  xHeight: Math.NaN
196017
196017
  };
196018
196018
  });
196019
+ function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) {
196020
+ const COMPONENTS = 3;
196021
+ alpha01 = alpha01 !== 1 ? 0 : alpha01;
196022
+ const xRatio = w1 / w2;
196023
+ const yRatio = h1 / h2;
196024
+ let newIndex = 0, oldIndex;
196025
+ const xScaled = new Uint16Array(w2);
196026
+ const w1Scanline = w1 * COMPONENTS;
196027
+ for (let i = 0; i < w2; i++) {
196028
+ xScaled[i] = Math.floor(i * xRatio) * COMPONENTS;
196029
+ }
196030
+ for (let i = 0; i < h2; i++) {
196031
+ const py = Math.floor(i * yRatio) * w1Scanline;
196032
+ for (let j = 0; j < w2; j++) {
196033
+ oldIndex = py + xScaled[j];
196034
+ dest[newIndex++] = src[oldIndex++];
196035
+ dest[newIndex++] = src[oldIndex++];
196036
+ dest[newIndex++] = src[oldIndex++];
196037
+ newIndex += alpha01;
196038
+ }
196039
+ }
196040
+ }
196041
+ function isDefaultDecodeHelper(decode3, expectedLen) {
196042
+ if (!Array.isArray(decode3)) {
196043
+ return true;
196044
+ }
196045
+ const decodeLen = decode3.length;
196046
+ if (decodeLen < expectedLen) {
196047
+ warn2("Decode map length is too short.");
196048
+ return true;
196049
+ }
196050
+ if (decodeLen > expectedLen) {
196051
+ info("Truncating too long decode map.");
196052
+ decode3.length = expectedLen;
196053
+ }
196054
+ return false;
196055
+ }
196056
+ var ColorSpace = class _ColorSpace {
196057
+ static #rgbBuf = new Uint8ClampedArray(3);
196058
+ constructor(name, numComps) {
196059
+ if ((typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) && this.constructor === _ColorSpace) {
196060
+ unreachable2("Cannot initialize ColorSpace.");
196061
+ }
196062
+ this.name = name;
196063
+ this.numComps = numComps;
196064
+ }
196065
+ /**
196066
+ * Converts the color value to the RGB color. The color components are
196067
+ * located in the src array starting from the srcOffset. Returns the array
196068
+ * of the rgb components, each value ranging from [0,255].
196069
+ */
196070
+ getRgb(src, srcOffset, output2 = new Uint8ClampedArray(3)) {
196071
+ this.getRgbItem(src, srcOffset, output2, 0);
196072
+ return output2;
196073
+ }
196074
+ getRgbHex(src, srcOffset) {
196075
+ const buffer = this.getRgb(src, srcOffset, _ColorSpace.#rgbBuf);
196076
+ return Util.makeHexColor(buffer[0], buffer[1], buffer[2]);
196077
+ }
196078
+ /**
196079
+ * Converts the color value to the RGB color, similar to the getRgb method.
196080
+ * The result placed into the dest array starting from the destOffset.
196081
+ */
196082
+ getRgbItem(src, srcOffset, dest, destOffset) {
196083
+ unreachable2("Should not call ColorSpace.getRgbItem");
196084
+ }
196085
+ /**
196086
+ * Converts the specified number of the color values to the RGB colors.
196087
+ * The colors are located in the src array starting from the srcOffset.
196088
+ * The result is placed into the dest array starting from the destOffset.
196089
+ * The src array items shall be in [0,2^bits) range, the dest array items
196090
+ * will be in [0,255] range. alpha01 indicates how many alpha components
196091
+ * there are in the dest array; it will be either 0 (RGB array) or 1 (RGBA
196092
+ * array).
196093
+ */
196094
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
196095
+ unreachable2("Should not call ColorSpace.getRgbBuffer");
196096
+ }
196097
+ /**
196098
+ * Converts `count` unscaled colors to RGB, starting at `destOffset`.
196099
+ * Components use the native color-space ranges expected by `getRgbItem`,
196100
+ * and each output has a `3 + alpha01` byte stride.
196101
+ * Subclasses may override this to batch expensive conversions.
196102
+ */
196103
+ getRgbItems(src, count, dest, destOffset, alpha01) {
196104
+ const { numComps } = this;
196105
+ for (let i = 0, srcOffset = 0; i < count; i++, srcOffset += numComps) {
196106
+ this.getRgbItem(src, srcOffset, dest, destOffset);
196107
+ destOffset += 3 + alpha01;
196108
+ }
196109
+ }
196110
+ /**
196111
+ * Returns true if source data will be equal the result/output data.
196112
+ */
196113
+ isPassthrough(bits) {
196114
+ return false;
196115
+ }
196116
+ /**
196117
+ * Refer to the static `ColorSpace.isDefaultDecode` method below.
196118
+ */
196119
+ isDefaultDecode(decode3, bpc) {
196120
+ return _ColorSpace.isDefaultDecode(decode3, this.numComps);
196121
+ }
196122
+ /**
196123
+ * Fills in the RGB colors in the destination buffer. alpha01 indicates
196124
+ * how many alpha components there are in the dest array; it will be either
196125
+ * 0 (RGB array) or 1 (RGBA array).
196126
+ */
196127
+ fillRgb(dest, originalWidth, originalHeight, width2, height, actualHeight, bpc, comps, alpha01) {
196128
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196129
+ assert2(
196130
+ dest instanceof Uint8ClampedArray,
196131
+ 'ColorSpace.fillRgb: Unsupported "dest" type.'
196132
+ );
196133
+ }
196134
+ const count = originalWidth * originalHeight;
196135
+ let rgbBuf = null;
196136
+ const numComponentColors = 1 << bpc;
196137
+ const needsResizing = originalHeight !== height || originalWidth !== width2;
196138
+ if (this.isPassthrough(bpc)) {
196139
+ rgbBuf = comps;
196140
+ } else if (this.numComps === 1 && count > numComponentColors && this.name !== "DeviceGray" && this.name !== "DeviceRGB") {
196141
+ const allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : new Uint16Array(numComponentColors);
196142
+ for (let i = 0; i < numComponentColors; i++) {
196143
+ allColors[i] = i;
196144
+ }
196145
+ const colorMap = new Uint8ClampedArray(numComponentColors * 3);
196146
+ this.getRgbBuffer(
196147
+ allColors,
196148
+ 0,
196149
+ numComponentColors,
196150
+ colorMap,
196151
+ 0,
196152
+ bpc,
196153
+ /* alpha01 = */
196154
+ 0
196155
+ );
196156
+ if (!needsResizing) {
196157
+ let destPos = 0;
196158
+ for (let i = 0; i < count; ++i) {
196159
+ const key = comps[i] * 3;
196160
+ dest[destPos++] = colorMap[key];
196161
+ dest[destPos++] = colorMap[key + 1];
196162
+ dest[destPos++] = colorMap[key + 2];
196163
+ destPos += alpha01;
196164
+ }
196165
+ } else {
196166
+ rgbBuf = new Uint8Array(count * 3);
196167
+ let rgbPos = 0;
196168
+ for (let i = 0; i < count; ++i) {
196169
+ const key = comps[i] * 3;
196170
+ rgbBuf[rgbPos++] = colorMap[key];
196171
+ rgbBuf[rgbPos++] = colorMap[key + 1];
196172
+ rgbBuf[rgbPos++] = colorMap[key + 2];
196173
+ }
196174
+ }
196175
+ } else if (!needsResizing) {
196176
+ this.getRgbBuffer(comps, 0, width2 * actualHeight, dest, 0, bpc, alpha01);
196177
+ } else {
196178
+ rgbBuf = new Uint8ClampedArray(count * 3);
196179
+ this.getRgbBuffer(
196180
+ comps,
196181
+ 0,
196182
+ count,
196183
+ rgbBuf,
196184
+ 0,
196185
+ bpc,
196186
+ /* alpha01 = */
196187
+ 0
196188
+ );
196189
+ }
196190
+ if (rgbBuf) {
196191
+ if (needsResizing) {
196192
+ resizeRgbImage(
196193
+ rgbBuf,
196194
+ dest,
196195
+ originalWidth,
196196
+ originalHeight,
196197
+ width2,
196198
+ height,
196199
+ alpha01
196200
+ );
196201
+ } else {
196202
+ let destPos = 0, rgbPos = 0;
196203
+ for (let i = 0, ii = width2 * actualHeight; i < ii; i++) {
196204
+ dest[destPos++] = rgbBuf[rgbPos++];
196205
+ dest[destPos++] = rgbBuf[rgbPos++];
196206
+ dest[destPos++] = rgbBuf[rgbPos++];
196207
+ destPos += alpha01;
196208
+ }
196209
+ }
196210
+ }
196211
+ }
196212
+ /**
196213
+ * True if the colorspace has components in the default range of [0, 1].
196214
+ * This should be true for all colorspaces except for lab color spaces
196215
+ * which are [0,100], [-128, 127], [-128, 127].
196216
+ */
196217
+ get usesZeroToOneRange() {
196218
+ return shadow2(this, "usesZeroToOneRange", true);
196219
+ }
196220
+ /**
196221
+ * Checks if a decode map matches the default decode map for a color space.
196222
+ * This handles the general decode maps where there are two values per
196223
+ * component, e.g. [0, 1, 0, 1, 0, 1] for a RGB color.
196224
+ * This does not handle Lab, Indexed, or Pattern decode maps since they are
196225
+ * slightly different.
196226
+ * @param {Array} decode - Decode map (usually from an image).
196227
+ * @param {number} numComps - Number of components the color space has.
196228
+ */
196229
+ static isDefaultDecode(decode3, numComps) {
196230
+ if (isDefaultDecodeHelper(decode3, numComps * 2)) {
196231
+ return true;
196232
+ }
196233
+ for (let i = 0, ii = decode3.length; i < ii; i += 2) {
196234
+ if (decode3[i] !== 0 || decode3[i + 1] !== 1) {
196235
+ return false;
196236
+ }
196237
+ }
196238
+ return true;
196239
+ }
196240
+ };
196241
+ var DeviceCmykCS = class extends ColorSpace {
196242
+ constructor() {
196243
+ super("DeviceCMYK", 4);
196244
+ }
196245
+ // The coefficients below was found using numerical analysis: the method of
196246
+ // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors,
196247
+ // where color_value is the tabular value from the table of sampled RGB colors
196248
+ // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding
196249
+ // CMYK color conversion using the estimation below:
196250
+ // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255
196251
+ #toRgb(src, srcOffset, srcScale, dest, destOffset) {
196252
+ const c4 = src[srcOffset] * srcScale;
196253
+ const m = src[srcOffset + 1] * srcScale;
196254
+ const y = src[srcOffset + 2] * srcScale;
196255
+ const k = src[srcOffset + 3] * srcScale;
196256
+ dest[destOffset] = 255 + c4 * (-4.387332384609988 * c4 + 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);
196257
+ dest[destOffset + 1] = 255 + c4 * (8.841041422036149 * c4 + 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);
196258
+ dest[destOffset + 2] = 255 + c4 * (0.8842522430003296 * c4 + 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);
196259
+ }
196260
+ getRgbItem(src, srcOffset, dest, destOffset) {
196261
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196262
+ assert2(
196263
+ dest instanceof Uint8ClampedArray,
196264
+ 'DeviceCmykCS.getRgbItem: Unsupported "dest" type.'
196265
+ );
196266
+ }
196267
+ this.#toRgb(src, srcOffset, 1, dest, destOffset);
196268
+ }
196269
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
196270
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196271
+ assert2(
196272
+ dest instanceof Uint8ClampedArray,
196273
+ 'DeviceCmykCS.getRgbBuffer: Unsupported "dest" type.'
196274
+ );
196275
+ }
196276
+ const scale2 = 1 / ((1 << bits) - 1);
196277
+ for (let i = 0; i < count; i++) {
196278
+ this.#toRgb(src, srcOffset, scale2, dest, destOffset);
196279
+ srcOffset += 4;
196280
+ destOffset += 3 + alpha01;
196281
+ }
196282
+ }
196283
+ };
196284
+ var CalGrayCS = class extends ColorSpace {
196285
+ constructor(whitePoint, blackPoint, gamma2) {
196286
+ super("CalGray", 1);
196287
+ if (!whitePoint) {
196288
+ throw new FormatError(
196289
+ "WhitePoint missing - required for color space CalGray"
196290
+ );
196291
+ }
196292
+ [this.XW, this.YW, this.ZW] = whitePoint;
196293
+ [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];
196294
+ this.G = gamma2 || 1;
196295
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
196296
+ throw new FormatError(
196297
+ `Invalid WhitePoint components for ${this.name}, no fallback available`
196298
+ );
196299
+ }
196300
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
196301
+ info(`Invalid BlackPoint for ${this.name}, falling back to default.`);
196302
+ this.XB = this.YB = this.ZB = 0;
196303
+ }
196304
+ if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
196305
+ warn2(
196306
+ `${this.name}, BlackPoint: XB: ${this.XB}, YB: ${this.YB}, ZB: ${this.ZB}, only default values are supported.`
196307
+ );
196308
+ }
196309
+ if (this.G < 1) {
196310
+ info(
196311
+ `Invalid Gamma: ${this.G} for ${this.name}, falling back to default.`
196312
+ );
196313
+ this.G = 1;
196314
+ }
196315
+ }
196316
+ #toRgb(src, srcOffset, dest, destOffset, scale2) {
196317
+ const A = src[srcOffset] * scale2;
196318
+ const AG = A ** this.G;
196319
+ const L = this.YW * AG;
196320
+ const val = Math.max(295.8 * L ** 0.3333333333333333 - 40.8, 0);
196321
+ dest[destOffset] = val;
196322
+ dest[destOffset + 1] = val;
196323
+ dest[destOffset + 2] = val;
196324
+ }
196325
+ getRgbItem(src, srcOffset, dest, destOffset) {
196326
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196327
+ assert2(
196328
+ dest instanceof Uint8ClampedArray,
196329
+ 'CalGrayCS.getRgbItem: Unsupported "dest" type.'
196330
+ );
196331
+ }
196332
+ this.#toRgb(src, srcOffset, dest, destOffset, 1);
196333
+ }
196334
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
196335
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196336
+ assert2(
196337
+ dest instanceof Uint8ClampedArray,
196338
+ 'CalGrayCS.getRgbBuffer: Unsupported "dest" type.'
196339
+ );
196340
+ }
196341
+ const scale2 = 1 / ((1 << bits) - 1);
196342
+ for (let i = 0; i < count; ++i) {
196343
+ this.#toRgb(src, srcOffset, dest, destOffset, scale2);
196344
+ srcOffset += 1;
196345
+ destOffset += 3 + alpha01;
196346
+ }
196347
+ }
196348
+ };
196349
+ var CalRGBCS = class _CalRGBCS extends ColorSpace {
196350
+ // See http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html for these
196351
+ // matrices.
196352
+ // prettier-ignore
196353
+ static #BRADFORD_SCALE_MATRIX = new Float32Array([
196354
+ 0.8951,
196355
+ 0.2664,
196356
+ -0.1614,
196357
+ -0.7502,
196358
+ 1.7135,
196359
+ 0.0367,
196360
+ 0.0389,
196361
+ -0.0685,
196362
+ 1.0296
196363
+ ]);
196364
+ // prettier-ignore
196365
+ static #BRADFORD_SCALE_INVERSE_MATRIX = new Float32Array([
196366
+ 0.9869929,
196367
+ -0.1470543,
196368
+ 0.1599627,
196369
+ 0.4323053,
196370
+ 0.5183603,
196371
+ 0.0492912,
196372
+ -85287e-7,
196373
+ 0.0400428,
196374
+ 0.9684867
196375
+ ]);
196376
+ // See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html.
196377
+ // prettier-ignore
196378
+ static #SRGB_D65_XYZ_TO_RGB_MATRIX = new Float32Array([
196379
+ 3.2404542,
196380
+ -1.5371385,
196381
+ -0.4985314,
196382
+ -0.969266,
196383
+ 1.8760108,
196384
+ 0.041556,
196385
+ 0.0556434,
196386
+ -0.2040259,
196387
+ 1.0572252
196388
+ ]);
196389
+ static #FLAT_WHITEPOINT_MATRIX = new Float32Array([1, 1, 1]);
196390
+ static #tempNormalizeMatrix = new Float32Array(3);
196391
+ static #tempConvertMatrix1 = new Float32Array(3);
196392
+ static #tempConvertMatrix2 = new Float32Array(3);
196393
+ static #DECODE_L_CONSTANT = ((8 + 16) / 116) ** 3 / 8;
196394
+ constructor(whitePoint, blackPoint, gamma2, matrix2) {
196395
+ super("CalRGB", 3);
196396
+ if (!whitePoint) {
196397
+ throw new FormatError(
196398
+ "WhitePoint missing - required for color space CalRGB"
196399
+ );
196400
+ }
196401
+ const [XW, YW, ZW] = this.whitePoint = whitePoint;
196402
+ const [XB, YB, ZB] = this.blackPoint = blackPoint || new Float32Array(3);
196403
+ [this.GR, this.GG, this.GB] = gamma2 || new Float32Array([1, 1, 1]);
196404
+ [
196405
+ this.MXA,
196406
+ this.MYA,
196407
+ this.MZA,
196408
+ this.MXB,
196409
+ this.MYB,
196410
+ this.MZB,
196411
+ this.MXC,
196412
+ this.MYC,
196413
+ this.MZC
196414
+ ] = matrix2 || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);
196415
+ if (XW < 0 || ZW < 0 || YW !== 1) {
196416
+ throw new FormatError(
196417
+ `Invalid WhitePoint components for ${this.name}, no fallback available`
196418
+ );
196419
+ }
196420
+ if (XB < 0 || YB < 0 || ZB < 0) {
196421
+ info(
196422
+ `Invalid BlackPoint for ${this.name} [${XB}, ${YB}, ${ZB}], falling back to default.`
196423
+ );
196424
+ this.blackPoint = new Float32Array(3);
196425
+ }
196426
+ if (this.GR < 0 || this.GG < 0 || this.GB < 0) {
196427
+ info(
196428
+ `Invalid Gamma [${this.GR}, ${this.GG}, ${this.GB}] for ${this.name}, falling back to default.`
196429
+ );
196430
+ this.GR = this.GG = this.GB = 1;
196431
+ }
196432
+ }
196433
+ #matrixProduct(a3, b3, result2) {
196434
+ result2[0] = a3[0] * b3[0] + a3[1] * b3[1] + a3[2] * b3[2];
196435
+ result2[1] = a3[3] * b3[0] + a3[4] * b3[1] + a3[5] * b3[2];
196436
+ result2[2] = a3[6] * b3[0] + a3[7] * b3[1] + a3[8] * b3[2];
196437
+ }
196438
+ #toFlat(sourceWhitePoint, LMS, result2) {
196439
+ result2[0] = LMS[0] * 1 / sourceWhitePoint[0];
196440
+ result2[1] = LMS[1] * 1 / sourceWhitePoint[1];
196441
+ result2[2] = LMS[2] * 1 / sourceWhitePoint[2];
196442
+ }
196443
+ #toD65(sourceWhitePoint, LMS, result2) {
196444
+ const D65X = 0.95047;
196445
+ const D65Y = 1;
196446
+ const D65Z = 1.08883;
196447
+ result2[0] = LMS[0] * D65X / sourceWhitePoint[0];
196448
+ result2[1] = LMS[1] * D65Y / sourceWhitePoint[1];
196449
+ result2[2] = LMS[2] * D65Z / sourceWhitePoint[2];
196450
+ }
196451
+ #sRGBTransferFunction(color5) {
196452
+ if (color5 <= 31308e-7) {
196453
+ return MathClamp(12.92 * color5, 0, 1);
196454
+ }
196455
+ return color5 >= 0.99554525 ? 1 : MathClamp((1 + 0.055) * color5 ** (1 / 2.4) - 0.055, 0, 1);
196456
+ }
196457
+ #decodeL(L) {
196458
+ if (L < 0) {
196459
+ return -this.#decodeL(-L);
196460
+ }
196461
+ return L > 8 ? ((L + 16) / 116) ** 3 : L * _CalRGBCS.#DECODE_L_CONSTANT;
196462
+ }
196463
+ #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result2) {
196464
+ if (sourceBlackPoint[0] === 0 && sourceBlackPoint[1] === 0 && sourceBlackPoint[2] === 0) {
196465
+ result2[0] = XYZ_Flat[0];
196466
+ result2[1] = XYZ_Flat[1];
196467
+ result2[2] = XYZ_Flat[2];
196468
+ return;
196469
+ }
196470
+ const zeroDecodeL = this.#decodeL(0);
196471
+ const X_DST = zeroDecodeL;
196472
+ const X_SRC = this.#decodeL(sourceBlackPoint[0]);
196473
+ const Y_DST = zeroDecodeL;
196474
+ const Y_SRC = this.#decodeL(sourceBlackPoint[1]);
196475
+ const Z_DST = zeroDecodeL;
196476
+ const Z_SRC = this.#decodeL(sourceBlackPoint[2]);
196477
+ const X_Scale = (1 - X_DST) / (1 - X_SRC);
196478
+ const X_Offset = 1 - X_Scale;
196479
+ const Y_Scale = (1 - Y_DST) / (1 - Y_SRC);
196480
+ const Y_Offset = 1 - Y_Scale;
196481
+ const Z_Scale = (1 - Z_DST) / (1 - Z_SRC);
196482
+ const Z_Offset = 1 - Z_Scale;
196483
+ result2[0] = XYZ_Flat[0] * X_Scale + X_Offset;
196484
+ result2[1] = XYZ_Flat[1] * Y_Scale + Y_Offset;
196485
+ result2[2] = XYZ_Flat[2] * Z_Scale + Z_Offset;
196486
+ }
196487
+ #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result2) {
196488
+ if (sourceWhitePoint[0] === 1 && sourceWhitePoint[2] === 1) {
196489
+ result2[0] = XYZ_In[0];
196490
+ result2[1] = XYZ_In[1];
196491
+ result2[2] = XYZ_In[2];
196492
+ return;
196493
+ }
196494
+ const LMS = result2;
196495
+ this.#matrixProduct(_CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);
196496
+ const LMS_Flat = _CalRGBCS.#tempNormalizeMatrix;
196497
+ this.#toFlat(sourceWhitePoint, LMS, LMS_Flat);
196498
+ this.#matrixProduct(
196499
+ _CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX,
196500
+ LMS_Flat,
196501
+ result2
196502
+ );
196503
+ }
196504
+ #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result2) {
196505
+ const LMS = result2;
196506
+ this.#matrixProduct(_CalRGBCS.#BRADFORD_SCALE_MATRIX, XYZ_In, LMS);
196507
+ const LMS_D65 = _CalRGBCS.#tempNormalizeMatrix;
196508
+ this.#toD65(sourceWhitePoint, LMS, LMS_D65);
196509
+ this.#matrixProduct(
196510
+ _CalRGBCS.#BRADFORD_SCALE_INVERSE_MATRIX,
196511
+ LMS_D65,
196512
+ result2
196513
+ );
196514
+ }
196515
+ #toRgb(src, srcOffset, dest, destOffset, scale2) {
196516
+ const A = MathClamp(src[srcOffset] * scale2, 0, 1);
196517
+ const B = MathClamp(src[srcOffset + 1] * scale2, 0, 1);
196518
+ const C = MathClamp(src[srcOffset + 2] * scale2, 0, 1);
196519
+ const AGR = A === 1 ? 1 : A ** this.GR;
196520
+ const BGG = B === 1 ? 1 : B ** this.GG;
196521
+ const CGB = C === 1 ? 1 : C ** this.GB;
196522
+ const X = this.MXA * AGR + this.MXB * BGG + this.MXC * CGB;
196523
+ const Y = this.MYA * AGR + this.MYB * BGG + this.MYC * CGB;
196524
+ const Z = this.MZA * AGR + this.MZB * BGG + this.MZC * CGB;
196525
+ const XYZ = _CalRGBCS.#tempConvertMatrix1;
196526
+ XYZ[0] = X;
196527
+ XYZ[1] = Y;
196528
+ XYZ[2] = Z;
196529
+ const XYZ_Flat = _CalRGBCS.#tempConvertMatrix2;
196530
+ this.#normalizeWhitePointToFlat(this.whitePoint, XYZ, XYZ_Flat);
196531
+ const XYZ_Black = _CalRGBCS.#tempConvertMatrix1;
196532
+ this.#compensateBlackPoint(this.blackPoint, XYZ_Flat, XYZ_Black);
196533
+ const XYZ_D65 = _CalRGBCS.#tempConvertMatrix2;
196534
+ this.#normalizeWhitePointToD65(
196535
+ _CalRGBCS.#FLAT_WHITEPOINT_MATRIX,
196536
+ XYZ_Black,
196537
+ XYZ_D65
196538
+ );
196539
+ const SRGB = _CalRGBCS.#tempConvertMatrix1;
196540
+ this.#matrixProduct(_CalRGBCS.#SRGB_D65_XYZ_TO_RGB_MATRIX, XYZ_D65, SRGB);
196541
+ dest[destOffset] = this.#sRGBTransferFunction(SRGB[0]) * 255;
196542
+ dest[destOffset + 1] = this.#sRGBTransferFunction(SRGB[1]) * 255;
196543
+ dest[destOffset + 2] = this.#sRGBTransferFunction(SRGB[2]) * 255;
196544
+ }
196545
+ getRgbItem(src, srcOffset, dest, destOffset) {
196546
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196547
+ assert2(
196548
+ dest instanceof Uint8ClampedArray,
196549
+ 'CalRGBCS.getRgbItem: Unsupported "dest" type.'
196550
+ );
196551
+ }
196552
+ this.#toRgb(src, srcOffset, dest, destOffset, 1);
196553
+ }
196554
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
196555
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196556
+ assert2(
196557
+ dest instanceof Uint8ClampedArray,
196558
+ 'CalRGBCS.getRgbBuffer: Unsupported "dest" type.'
196559
+ );
196560
+ }
196561
+ const scale2 = 1 / ((1 << bits) - 1);
196562
+ for (let i = 0; i < count; ++i) {
196563
+ this.#toRgb(src, srcOffset, dest, destOffset, scale2);
196564
+ srcOffset += 3;
196565
+ destOffset += 3 + alpha01;
196566
+ }
196567
+ }
196568
+ };
196569
+ var LabCS = class extends ColorSpace {
196570
+ constructor(whitePoint, blackPoint, range3) {
196571
+ super("Lab", 3);
196572
+ if (!whitePoint) {
196573
+ throw new FormatError(
196574
+ "WhitePoint missing - required for color space Lab"
196575
+ );
196576
+ }
196577
+ [this.XW, this.YW, this.ZW] = whitePoint;
196578
+ [this.amin, this.amax, this.bmin, this.bmax] = range3 || [
196579
+ -100,
196580
+ 100,
196581
+ -100,
196582
+ 100
196583
+ ];
196584
+ [this.XB, this.YB, this.ZB] = blackPoint || [0, 0, 0];
196585
+ if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
196586
+ throw new FormatError(
196587
+ "Invalid WhitePoint components, no fallback available"
196588
+ );
196589
+ }
196590
+ if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
196591
+ info("Invalid BlackPoint, falling back to default");
196592
+ this.XB = this.YB = this.ZB = 0;
196593
+ }
196594
+ if (this.amin > this.amax || this.bmin > this.bmax) {
196595
+ info("Invalid Range, falling back to defaults");
196596
+ this.amin = -100;
196597
+ this.amax = 100;
196598
+ this.bmin = -100;
196599
+ this.bmax = 100;
196600
+ }
196601
+ }
196602
+ // Function g(x) from spec
196603
+ #fn_g(x) {
196604
+ return x >= 6 / 29 ? x ** 3 : 108 / 841 * (x - 4 / 29);
196605
+ }
196606
+ #decode(value3, high1, low2, high2) {
196607
+ return low2 + value3 * (high2 - low2) / high1;
196608
+ }
196609
+ // If decoding is needed maxVal should be 2^bits per component - 1.
196610
+ #toRgb(src, srcOffset, maxVal, dest, destOffset) {
196611
+ let Ls = src[srcOffset];
196612
+ let as = src[srcOffset + 1];
196613
+ let bs = src[srcOffset + 2];
196614
+ if (maxVal !== false) {
196615
+ Ls = this.#decode(Ls, maxVal, 0, 100);
196616
+ as = this.#decode(as, maxVal, this.amin, this.amax);
196617
+ bs = this.#decode(bs, maxVal, this.bmin, this.bmax);
196618
+ }
196619
+ if (as > this.amax) {
196620
+ as = this.amax;
196621
+ } else if (as < this.amin) {
196622
+ as = this.amin;
196623
+ }
196624
+ if (bs > this.bmax) {
196625
+ bs = this.bmax;
196626
+ } else if (bs < this.bmin) {
196627
+ bs = this.bmin;
196628
+ }
196629
+ const M = (Ls + 16) / 116;
196630
+ const L = M + as / 500;
196631
+ const N = M - bs / 200;
196632
+ const X = this.XW * this.#fn_g(L);
196633
+ const Y = this.YW * this.#fn_g(M);
196634
+ const Z = this.ZW * this.#fn_g(N);
196635
+ let r, g, b3;
196636
+ if (this.ZW < 1) {
196637
+ r = X * 3.1339 + Y * -1.617 + Z * -0.4906;
196638
+ g = X * -0.9785 + Y * 1.916 + Z * 0.0333;
196639
+ b3 = X * 0.072 + Y * -0.229 + Z * 1.4057;
196640
+ } else {
196641
+ r = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
196642
+ g = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
196643
+ b3 = X * 0.0557 + Y * -0.204 + Z * 1.057;
196644
+ }
196645
+ dest[destOffset] = Math.sqrt(r) * 255;
196646
+ dest[destOffset + 1] = Math.sqrt(g) * 255;
196647
+ dest[destOffset + 2] = Math.sqrt(b3) * 255;
196648
+ }
196649
+ getRgbItem(src, srcOffset, dest, destOffset) {
196650
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196651
+ assert2(
196652
+ dest instanceof Uint8ClampedArray,
196653
+ 'LabCS.getRgbItem: Unsupported "dest" type.'
196654
+ );
196655
+ }
196656
+ this.#toRgb(src, srcOffset, false, dest, destOffset);
196657
+ }
196658
+ getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
196659
+ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
196660
+ assert2(
196661
+ dest instanceof Uint8ClampedArray,
196662
+ 'LabCS.getRgbBuffer: Unsupported "dest" type.'
196663
+ );
196664
+ }
196665
+ const maxVal = (1 << bits) - 1;
196666
+ for (let i = 0; i < count; i++) {
196667
+ this.#toRgb(src, srcOffset, maxVal, dest, destOffset);
196668
+ srcOffset += 3;
196669
+ destOffset += 3 + alpha01;
196670
+ }
196671
+ }
196672
+ isDefaultDecode(decode3, bpc) {
196673
+ return true;
196674
+ }
196675
+ get usesZeroToOneRange() {
196676
+ return shadow2(this, "usesZeroToOneRange", false);
196677
+ }
196678
+ };
196679
+ var TOKEN = {
196680
+ // Structural tokens — not keyword operators
196681
+ number: 0,
196682
+ lbrace: 1,
196683
+ rbrace: 2,
196684
+ // Boolean literals
196685
+ true: 3,
196686
+ false: 4,
196687
+ // Arithmetic binary operators
196688
+ add: 5,
196689
+ sub: 6,
196690
+ mul: 7,
196691
+ div: 8,
196692
+ idiv: 9,
196693
+ mod: 10,
196694
+ exp: 11,
196695
+ // Comparison binary operators
196696
+ eq: 12,
196697
+ ne: 13,
196698
+ gt: 14,
196699
+ ge: 15,
196700
+ lt: 16,
196701
+ le: 17,
196702
+ // Bitwise / boolean binary operators
196703
+ and: 18,
196704
+ or: 19,
196705
+ xor: 20,
196706
+ bitshift: 21,
196707
+ // Unary arithmetic operators
196708
+ abs: 22,
196709
+ neg: 23,
196710
+ ceiling: 24,
196711
+ floor: 25,
196712
+ round: 26,
196713
+ truncate: 27,
196714
+ // Unary boolean / bitwise operator
196715
+ not: 28,
196716
+ // Mathematical functions — unary
196717
+ sqrt: 29,
196718
+ sin: 30,
196719
+ cos: 31,
196720
+ ln: 32,
196721
+ log: 33,
196722
+ // Mathematical function — binary
196723
+ atan: 34,
196724
+ // Type conversion operators
196725
+ cvi: 35,
196726
+ cvr: 36,
196727
+ // Stack operators
196728
+ dup: 37,
196729
+ exch: 38,
196730
+ pop: 39,
196731
+ copy: 40,
196732
+ index: 41,
196733
+ roll: 42,
196734
+ // Control flow
196735
+ if: 43,
196736
+ ifelse: 44,
196737
+ // End of input
196738
+ eof: 45,
196739
+ // Synthetic: produced by the optimizer, never emitted by the lexer.
196740
+ min: 46,
196741
+ max: 47
196742
+ };
196743
+ var Token = class {
196744
+ constructor(id, value3 = null) {
196745
+ this.id = id;
196746
+ this.value = value3;
196747
+ }
196748
+ };
196749
+ var Lexer = class _Lexer {
196750
+ // Singletons for every non-number token, built lazily on first construction.
196751
+ // Keyword operator tokens carry their name as `value`; structural tokens
196752
+ // (lbrace, rbrace, eof) carry null.
196753
+ static #singletons = null;
196754
+ static #operatorSingletons = null;
196755
+ static #initSingletons() {
196756
+ const singletons = /* @__PURE__ */ Object.create(null);
196757
+ const operatorSingletons = /* @__PURE__ */ Object.create(null);
196758
+ for (const [name, id] of Object.entries(TOKEN)) {
196759
+ if (name === "number") {
196760
+ continue;
196761
+ }
196762
+ const isOperator = id >= TOKEN.true && id <= TOKEN.ifelse;
196763
+ const token = new Token(id, isOperator ? name : null);
196764
+ singletons[name] = token;
196765
+ if (isOperator) {
196766
+ operatorSingletons[name] = token;
196767
+ }
196768
+ }
196769
+ this.#singletons = singletons;
196770
+ this.#operatorSingletons = operatorSingletons;
196771
+ }
196772
+ constructor(data3) {
196773
+ if (!_Lexer.#singletons) {
196774
+ _Lexer.#initSingletons();
196775
+ }
196776
+ this.data = data3;
196777
+ this.pos = 0;
196778
+ this.len = data3.length;
196779
+ this._numberPattern = /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/iy;
196780
+ this._identifierPattern = /[a-z]+/y;
196781
+ }
196782
+ // Skip a % comment, advancing past the next \n or \r (or to EOF).
196783
+ _skipComment() {
196784
+ const lf = this.data.indexOf("\n", this.pos);
196785
+ const cr = this.data.indexOf("\r", this.pos);
196786
+ const eol = Math.min(lf < 0 ? this.len : lf, cr < 0 ? this.len : cr);
196787
+ this.pos = Math.min(eol + 1, this.len);
196788
+ }
196789
+ _getNumber() {
196790
+ this._numberPattern.lastIndex = this.pos;
196791
+ const match3 = this._numberPattern.exec(this.data);
196792
+ if (!match3) {
196793
+ return new Token(TOKEN.number, 0);
196794
+ }
196795
+ const number5 = parseFloat(match3[0]);
196796
+ if (!Number.isFinite(number5)) {
196797
+ return new Token(TOKEN.number, 0);
196798
+ }
196799
+ this.pos = this._numberPattern.lastIndex;
196800
+ return new Token(TOKEN.number, number5);
196801
+ }
196802
+ _getOperator() {
196803
+ this._identifierPattern.lastIndex = this.pos;
196804
+ const match3 = this._identifierPattern.exec(this.data);
196805
+ if (!match3) {
196806
+ return new Token(TOKEN.number, 0);
196807
+ }
196808
+ this.pos = this._identifierPattern.lastIndex;
196809
+ const op = match3[0];
196810
+ const token = _Lexer.#operatorSingletons[op];
196811
+ return token ?? new Token(TOKEN.number, 0);
196812
+ }
196813
+ // Return the next token, or Lexer.#singletons.eof at end of input.
196814
+ next() {
196815
+ while (this.pos < this.len) {
196816
+ const ch3 = this.data.charCodeAt(this.pos++);
196817
+ switch (ch3) {
196818
+ // PostScript white-space characters (PDF32000 §7.2.2)
196819
+ case 0:
196820
+ case 9:
196821
+ case 10:
196822
+ case 12:
196823
+ case 13:
196824
+ case 32:
196825
+ break;
196826
+ case 37:
196827
+ this._skipComment();
196828
+ break;
196829
+ case 123:
196830
+ return _Lexer.#singletons.lbrace;
196831
+ case 125:
196832
+ return _Lexer.#singletons.rbrace;
196833
+ case 43:
196834
+ case 45:
196835
+ this.pos--;
196836
+ return this._getNumber();
196837
+ case 46:
196838
+ this.pos--;
196839
+ return this._getNumber();
196840
+ default:
196841
+ if (ch3 >= 48 && ch3 <= 57) {
196842
+ this.pos--;
196843
+ return this._getNumber();
196844
+ }
196845
+ if (ch3 >= 97 && ch3 <= 122) {
196846
+ this.pos--;
196847
+ return this._getOperator();
196848
+ }
196849
+ return new Token(TOKEN.number, 0);
196850
+ }
196851
+ }
196852
+ return _Lexer.#singletons.eof;
196853
+ }
196854
+ };
196855
+ var PS_VALUE_TYPE = {
196856
+ numeric: 0,
196857
+ // known to be a number (f64 in Wasm)
196858
+ boolean: 1,
196859
+ // known to be a boolean (0.0 = false, 1.0 = true in f64)
196860
+ unknown: 2
196861
+ // indeterminate at compile time
196862
+ };
196863
+ var PS_NODE = {
196864
+ // Parser AST node types (produced by Parser / parsePostScriptFunction)
196865
+ program: 0,
196866
+ block: 1,
196867
+ number: 2,
196868
+ operator: 3,
196869
+ if: 4,
196870
+ ifelse: 5,
196871
+ // Tree AST node types (produced by PSStackToTree)
196872
+ arg: 6,
196873
+ const: 7,
196874
+ unary: 8,
196875
+ binary: 9,
196876
+ ternary: 10
196877
+ };
196878
+ var PsNode = class {
196879
+ constructor(type) {
196880
+ this.type = type;
196881
+ }
196882
+ };
196883
+ var PsProgram = class extends PsNode {
196884
+ constructor(body) {
196885
+ super(PS_NODE.program);
196886
+ this.body = body;
196887
+ }
196888
+ };
196889
+ var PsBlock = class extends PsNode {
196890
+ constructor(instructions) {
196891
+ super(PS_NODE.block);
196892
+ this.instructions = instructions;
196893
+ }
196894
+ };
196895
+ var PsNumber = class extends PsNode {
196896
+ /** @param {number} value */
196897
+ constructor(value3) {
196898
+ super(PS_NODE.number);
196899
+ this.value = value3;
196900
+ }
196901
+ };
196902
+ var PsOperator = class extends PsNode {
196903
+ /** @param {number} op — one of the TOKEN.* constants from lexer.js */
196904
+ constructor(op) {
196905
+ super(PS_NODE.operator);
196906
+ this.op = op;
196907
+ }
196908
+ };
196909
+ var PsIf = class extends PsNode {
196910
+ /** @param {PsBlock} then */
196911
+ constructor(then) {
196912
+ super(PS_NODE.if);
196913
+ this.then = then;
196914
+ }
196915
+ };
196916
+ var PsIfElse = class extends PsNode {
196917
+ /**
196918
+ * @param {PsBlock} then
196919
+ * @param {PsBlock} otherwise
196920
+ */
196921
+ constructor(then, otherwise) {
196922
+ super(PS_NODE.ifelse);
196923
+ this.then = then;
196924
+ this.otherwise = otherwise;
196925
+ }
196926
+ };
196927
+ var PsArgNode = class extends PsNode {
196928
+ /** @param {number} index */
196929
+ constructor(index2) {
196930
+ super(PS_NODE.arg);
196931
+ this.index = index2;
196932
+ this.valueType = PS_VALUE_TYPE.numeric;
196933
+ }
196934
+ };
196935
+ var PsConstNode = class extends PsNode {
196936
+ /** @param {number|boolean} value */
196937
+ constructor(value3) {
196938
+ super(PS_NODE.const);
196939
+ this.value = value3;
196940
+ this.valueType = typeof value3 === "boolean" ? PS_VALUE_TYPE.boolean : PS_VALUE_TYPE.numeric;
196941
+ }
196942
+ };
196943
+ var PsUnaryNode = class extends PsNode {
196944
+ /**
196945
+ * @param {number} op — TOKEN.* constant
196946
+ * @param {PsNode} operand
196947
+ * @param {number} [valueType]
196948
+ */
196949
+ constructor(op, operand, valueType = PS_VALUE_TYPE.unknown) {
196950
+ super(PS_NODE.unary);
196951
+ this.op = op;
196952
+ this.operand = operand;
196953
+ this.valueType = valueType;
196954
+ }
196955
+ };
196956
+ var PsBinaryNode = class extends PsNode {
196957
+ /**
196958
+ * @param {number} op — TOKEN.* constant
196959
+ * @param {PsNode} first — was on top of stack
196960
+ * @param {PsNode} second — was below top
196961
+ * @param {number} [valueType]
196962
+ */
196963
+ constructor(op, first, second, valueType = PS_VALUE_TYPE.unknown) {
196964
+ super(PS_NODE.binary);
196965
+ this.op = op;
196966
+ this.first = first;
196967
+ this.second = second;
196968
+ this.valueType = valueType;
196969
+ }
196970
+ };
196971
+ var PsTernaryNode = class extends PsNode {
196972
+ /**
196973
+ * @param {PsNode} cond
196974
+ * @param {PsNode} then
196975
+ * @param {PsNode} otherwise
196976
+ * @param {number} [valueType]
196977
+ */
196978
+ constructor(cond, then, otherwise, valueType = PS_VALUE_TYPE.unknown) {
196979
+ super(PS_NODE.ternary);
196980
+ this.cond = cond;
196981
+ this.then = then;
196982
+ this.otherwise = otherwise;
196983
+ this.valueType = valueType;
196984
+ }
196985
+ };
196986
+ var Parser2 = class _Parser {
196987
+ constructor(lexer) {
196988
+ this.lexer = lexer;
196989
+ this._token = null;
196990
+ }
196991
+ static _isRegularOperator(id) {
196992
+ return id >= TOKEN.true && id < TOKEN.if;
196993
+ }
196994
+ // Fetch the next token from the lexer.
196995
+ _advance() {
196996
+ this._token = this.lexer.next();
196997
+ }
196998
+ // Assert that the current token has the given id, consume it, and return it.
196999
+ _expect(id) {
197000
+ if (this._token.id !== id) {
197001
+ throw new FormatError(
197002
+ `PostScript function: expected token id ${id}, got ${this._token.id}.`
197003
+ );
197004
+ }
197005
+ const tok = this._token;
197006
+ this._advance();
197007
+ return tok;
197008
+ }
197009
+ /**
197010
+ * Parse the full Type 4 function body.
197011
+ *
197012
+ * Grammar (simplified):
197013
+ * program ::= '{' block '}'
197014
+ * block ::= instruction*
197015
+ * instruction ::= number
197016
+ * | operator (any PS_OPERATOR except if / ifelse)
197017
+ * | '{' block '}' 'if'
197018
+ * | '{' block '}' '{' block '}' 'ifelse'
197019
+ * @returns {PsProgram}
197020
+ */
197021
+ parse() {
197022
+ this._advance();
197023
+ this._expect(TOKEN.lbrace);
197024
+ const block2 = this._parseBlock();
197025
+ this._expect(TOKEN.rbrace);
197026
+ if (this._token.id !== TOKEN.eof) {
197027
+ warn2("PostScript function: unexpected content after closing brace.");
197028
+ }
197029
+ return new PsProgram(block2);
197030
+ }
197031
+ _parseBlock() {
197032
+ const instructions = [];
197033
+ while (true) {
197034
+ const tok = this._token;
197035
+ switch (tok.id) {
197036
+ case TOKEN.number:
197037
+ instructions.push(new PsNumber(tok.value));
197038
+ this._advance();
197039
+ break;
197040
+ case TOKEN.lbrace: {
197041
+ this._advance();
197042
+ const thenBlock = this._parseBlock();
197043
+ this._expect(TOKEN.rbrace);
197044
+ if (this._token.id === TOKEN.if) {
197045
+ this._advance();
197046
+ instructions.push(new PsIf(thenBlock));
197047
+ } else if (this._token.id === TOKEN.lbrace) {
197048
+ this._advance();
197049
+ const elseBlock = this._parseBlock();
197050
+ this._expect(TOKEN.rbrace);
197051
+ this._expect(TOKEN.ifelse);
197052
+ instructions.push(new PsIfElse(thenBlock, elseBlock));
197053
+ } else {
197054
+ throw new FormatError(
197055
+ "PostScript function: a procedure block must be followed by 'if' or '{\u2026} ifelse'."
197056
+ );
197057
+ }
197058
+ break;
197059
+ }
197060
+ case TOKEN.rbrace:
197061
+ case TOKEN.eof:
197062
+ return new PsBlock(instructions);
197063
+ case TOKEN.if:
197064
+ case TOKEN.ifelse:
197065
+ throw new FormatError(
197066
+ `PostScript function: unexpected '${tok.value}' operator.`
197067
+ );
197068
+ default:
197069
+ if (_Parser._isRegularOperator(tok.id)) {
197070
+ instructions.push(new PsOperator(tok.id));
197071
+ this._advance();
197072
+ break;
197073
+ }
197074
+ throw new FormatError(
197075
+ `PostScript function: unexpected token id ${tok.id}.`
197076
+ );
197077
+ }
197078
+ }
197079
+ }
197080
+ };
197081
+ function parsePostScriptFunction(source) {
197082
+ return new Parser2(new Lexer(source)).parse();
197083
+ }
197084
+ function _nodesEqual(a3, b3) {
197085
+ if (a3 === b3) {
197086
+ return true;
197087
+ }
197088
+ if (a3.type !== b3.type) {
197089
+ return false;
197090
+ }
197091
+ switch (a3.type) {
197092
+ case PS_NODE.arg:
197093
+ return a3.index === b3.index;
197094
+ case PS_NODE.const:
197095
+ return a3.value === b3.value;
197096
+ case PS_NODE.unary:
197097
+ return a3.op === b3.op && _nodesEqual(a3.operand, b3.operand);
197098
+ case PS_NODE.binary:
197099
+ return a3.op === b3.op && _nodesEqual(a3.first, b3.first) && _nodesEqual(a3.second, b3.second);
197100
+ case PS_NODE.ternary:
197101
+ return _nodesEqual(a3.cond, b3.cond) && _nodesEqual(a3.then, b3.then) && _nodesEqual(a3.otherwise, b3.otherwise);
197102
+ default:
197103
+ return false;
197104
+ }
197105
+ }
197106
+ function _evalBinaryConst(op, a3, b3) {
197107
+ switch (op) {
197108
+ case TOKEN.add:
197109
+ return a3 + b3;
197110
+ case TOKEN.sub:
197111
+ return a3 - b3;
197112
+ case TOKEN.mul:
197113
+ return a3 * b3;
197114
+ case TOKEN.div:
197115
+ return b3 !== 0 ? a3 / b3 : 0;
197116
+ // div by zero → 0
197117
+ case TOKEN.idiv:
197118
+ return b3 !== 0 ? Math.trunc(a3 / b3) : 0;
197119
+ // div by zero → 0
197120
+ case TOKEN.mod:
197121
+ return b3 !== 0 ? a3 - Math.trunc(a3 / b3) * b3 : 0;
197122
+ // div by zero → 0
197123
+ case TOKEN.exp: {
197124
+ const r = a3 ** b3;
197125
+ return Number.isFinite(r) ? r : void 0;
197126
+ }
197127
+ case TOKEN.atan: {
197128
+ let deg = Math.atan2(a3, b3) * (180 / Math.PI);
197129
+ if (deg < 0) {
197130
+ deg += 360;
197131
+ }
197132
+ return deg;
197133
+ }
197134
+ case TOKEN.eq:
197135
+ return a3 === b3;
197136
+ case TOKEN.ne:
197137
+ return a3 !== b3;
197138
+ case TOKEN.gt:
197139
+ return a3 > b3;
197140
+ case TOKEN.ge:
197141
+ return a3 >= b3;
197142
+ case TOKEN.lt:
197143
+ return a3 < b3;
197144
+ case TOKEN.le:
197145
+ return a3 <= b3;
197146
+ case TOKEN.and:
197147
+ return typeof a3 === "boolean" ? a3 && b3 : a3 & b3 | 0;
197148
+ case TOKEN.or:
197149
+ return typeof a3 === "boolean" ? a3 || b3 : a3 | b3 | 0;
197150
+ case TOKEN.xor:
197151
+ return typeof a3 === "boolean" ? a3 !== b3 : a3 ^ b3 | 0;
197152
+ case TOKEN.bitshift:
197153
+ return b3 >= 0 ? a3 << b3 | 0 : a3 >> -b3 | 0;
197154
+ case TOKEN.min:
197155
+ return Math.min(a3, b3);
197156
+ case TOKEN.max:
197157
+ return Math.max(a3, b3);
197158
+ default:
197159
+ return void 0;
197160
+ }
197161
+ }
197162
+ function _evalUnaryConst(op, v) {
197163
+ switch (op) {
197164
+ case TOKEN.abs:
197165
+ return Math.abs(v);
197166
+ case TOKEN.neg:
197167
+ return -v;
197168
+ case TOKEN.ceiling:
197169
+ return Math.ceil(v);
197170
+ case TOKEN.floor:
197171
+ return Math.floor(v);
197172
+ case TOKEN.round:
197173
+ return Math.round(v);
197174
+ case TOKEN.truncate:
197175
+ return Math.trunc(v);
197176
+ case TOKEN.sqrt: {
197177
+ const r = Math.sqrt(v);
197178
+ return Number.isFinite(r) ? r : void 0;
197179
+ }
197180
+ case TOKEN.sin:
197181
+ return Math.sin(v % 360 * Math.PI / 180);
197182
+ case TOKEN.cos:
197183
+ return Math.cos(v % 360 * Math.PI / 180);
197184
+ case TOKEN.ln: {
197185
+ const r = Math.log(v);
197186
+ return Number.isFinite(r) ? r : void 0;
197187
+ }
197188
+ case TOKEN.log: {
197189
+ const r = Math.log10(v);
197190
+ return Number.isFinite(r) ? r : void 0;
197191
+ }
197192
+ case TOKEN.cvi:
197193
+ return Math.trunc(v);
197194
+ case TOKEN.cvr:
197195
+ return v;
197196
+ case TOKEN.not:
197197
+ return typeof v === "boolean" ? !v : ~v;
197198
+ default:
197199
+ return void 0;
197200
+ }
197201
+ }
197202
+ var MAX_STACK_SIZE = 100;
197203
+ function _unaryValueType(op, operandType) {
197204
+ return op === TOKEN.not ? operandType : PS_VALUE_TYPE.numeric;
197205
+ }
197206
+ function _binaryValueType(op, firstType, secondType) {
197207
+ switch (op) {
197208
+ // Comparison operators always produce a boolean.
197209
+ case TOKEN.eq:
197210
+ case TOKEN.ne:
197211
+ case TOKEN.gt:
197212
+ case TOKEN.ge:
197213
+ case TOKEN.lt:
197214
+ case TOKEN.le:
197215
+ return PS_VALUE_TYPE.boolean;
197216
+ // and / or / xor preserve the type when both operands are the same known
197217
+ // type (both boolean or both numeric); otherwise the type is unknown.
197218
+ case TOKEN.and:
197219
+ case TOKEN.or:
197220
+ case TOKEN.xor:
197221
+ return firstType === secondType && firstType !== PS_VALUE_TYPE.unknown ? firstType : PS_VALUE_TYPE.unknown;
197222
+ // All arithmetic / bitshift operators produce a numeric result.
197223
+ default:
197224
+ return PS_VALUE_TYPE.numeric;
197225
+ }
197226
+ }
197227
+ var PSStackToTree = class _PSStackToTree {
197228
+ static #binaryOps = null;
197229
+ static #unaryOps = null;
197230
+ static #idempotentUnary = null;
197231
+ static #negatedComparison = null;
197232
+ static #init() {
197233
+ this.#binaryOps = /* @__PURE__ */ new Set([
197234
+ TOKEN.add,
197235
+ TOKEN.sub,
197236
+ TOKEN.mul,
197237
+ TOKEN.div,
197238
+ TOKEN.idiv,
197239
+ TOKEN.mod,
197240
+ TOKEN.exp,
197241
+ TOKEN.atan,
197242
+ TOKEN.eq,
197243
+ TOKEN.ne,
197244
+ TOKEN.gt,
197245
+ TOKEN.ge,
197246
+ TOKEN.lt,
197247
+ TOKEN.le,
197248
+ TOKEN.and,
197249
+ TOKEN.or,
197250
+ TOKEN.xor,
197251
+ TOKEN.bitshift
197252
+ ]);
197253
+ this.#unaryOps = /* @__PURE__ */ new Set([
197254
+ TOKEN.abs,
197255
+ TOKEN.neg,
197256
+ TOKEN.ceiling,
197257
+ TOKEN.floor,
197258
+ TOKEN.round,
197259
+ TOKEN.truncate,
197260
+ TOKEN.sqrt,
197261
+ TOKEN.sin,
197262
+ TOKEN.cos,
197263
+ TOKEN.ln,
197264
+ TOKEN.log,
197265
+ TOKEN.cvi,
197266
+ TOKEN.cvr,
197267
+ TOKEN.not
197268
+ ]);
197269
+ this.#idempotentUnary = /* @__PURE__ */ new Set([
197270
+ TOKEN.abs,
197271
+ TOKEN.ceiling,
197272
+ TOKEN.cvi,
197273
+ TOKEN.cvr,
197274
+ TOKEN.floor,
197275
+ TOKEN.round,
197276
+ TOKEN.truncate
197277
+ ]);
197278
+ this.#negatedComparison = /* @__PURE__ */ new Map([
197279
+ [TOKEN.eq, TOKEN.ne],
197280
+ [TOKEN.ne, TOKEN.eq],
197281
+ [TOKEN.lt, TOKEN.ge],
197282
+ [TOKEN.le, TOKEN.gt],
197283
+ [TOKEN.gt, TOKEN.le],
197284
+ [TOKEN.ge, TOKEN.lt]
197285
+ ]);
197286
+ }
197287
+ /**
197288
+ * @param {PsProgram} program
197289
+ * @param {number} numInputs — number of domain values placed on the stack
197290
+ * before the program runs (i.e. the length of the domain array / 2).
197291
+ * @returns {Array<PsNode>} — one tree node per output value.
197292
+ */
197293
+ evaluate(program, numInputs) {
197294
+ if (!_PSStackToTree.#binaryOps) {
197295
+ _PSStackToTree.#init();
197296
+ }
197297
+ this._failed = false;
197298
+ if (numInputs > MAX_STACK_SIZE) {
197299
+ return null;
197300
+ }
197301
+ const stack = [];
197302
+ for (let i = 0; i < numInputs; i++) {
197303
+ stack.push(new PsArgNode(i));
197304
+ }
197305
+ this._evalBlock(program.body, stack);
197306
+ if (this._failed) {
197307
+ return null;
197308
+ }
197309
+ _PSStackToTree.#markShared(stack);
197310
+ return stack;
197311
+ }
197312
+ // Set node.shared / sharedCount on non-atomic nodes referenced more than
197313
+ // once. arg/const are excluded — they are cheap to re-emit inline.
197314
+ static #markShared(outputs) {
197315
+ const refCount = /* @__PURE__ */ new Map();
197316
+ const visit = (node3) => {
197317
+ if (!node3 || node3.type === PS_NODE.arg || node3.type === PS_NODE.const) {
197318
+ return;
197319
+ }
197320
+ const prev = refCount.get(node3) ?? 0;
197321
+ refCount.set(node3, prev + 1);
197322
+ if (prev > 0) {
197323
+ return;
197324
+ }
197325
+ switch (node3.type) {
197326
+ case PS_NODE.unary:
197327
+ visit(node3.operand);
197328
+ break;
197329
+ case PS_NODE.binary:
197330
+ visit(node3.first);
197331
+ visit(node3.second);
197332
+ break;
197333
+ case PS_NODE.ternary:
197334
+ visit(node3.cond);
197335
+ visit(node3.then);
197336
+ visit(node3.otherwise);
197337
+ break;
197338
+ }
197339
+ };
197340
+ for (const output2 of outputs) {
197341
+ visit(output2);
197342
+ }
197343
+ for (const [node3, count] of refCount) {
197344
+ if (count > 1) {
197345
+ node3.shared = true;
197346
+ node3.sharedCount = count;
197347
+ }
197348
+ }
197349
+ }
197350
+ _evalBlock(block2, stack) {
197351
+ this._evalBlockFrom(block2.instructions, 0, stack);
197352
+ }
197353
+ /**
197354
+ * Core evaluation loop. Processes `instructions[startIdx…]` in order,
197355
+ * mutating `stack` as each instruction executes.
197356
+ *
197357
+ * When a `{ body } if` instruction grows the stack (the PostScript "early
197358
+ * exit / guard" idiom), the remaining instructions in the current array are
197359
+ * evaluated on **both** the true-branch stack and the false-branch stack,
197360
+ * then the two results are merged into PsTernaryNodes. This handles
197361
+ * patterns like:
197362
+ *
197363
+ * cond { pop R G B sentinel } if
197364
+ * … more guards …
197365
+ * sentinel 0 gt { defaultR defaultG defaultB } if
197366
+ */
197367
+ _evalBlockFrom(instructions, startIdx, stack) {
197368
+ for (let idx = startIdx; idx < instructions.length; idx++) {
197369
+ if (this._failed) {
197370
+ break;
197371
+ }
197372
+ const instr = instructions[idx];
197373
+ switch (instr.type) {
197374
+ case PS_NODE.number:
197375
+ stack.push(new PsConstNode(instr.value));
197376
+ if (stack.length > MAX_STACK_SIZE) {
197377
+ this._failed = true;
197378
+ }
197379
+ break;
197380
+ case PS_NODE.operator:
197381
+ this._evalOp(instr.op, stack);
197382
+ break;
197383
+ case PS_NODE.if: {
197384
+ if (stack.length < 1) {
197385
+ this._failed = true;
197386
+ break;
197387
+ }
197388
+ const cond = stack.pop();
197389
+ const saved = stack.slice();
197390
+ this._evalBlock(instr.then, stack);
197391
+ if (this._failed) {
197392
+ break;
197393
+ }
197394
+ if (stack.length === saved.length) {
197395
+ for (let i = 0; i < stack.length; i++) {
197396
+ if (stack[i] !== saved[i]) {
197397
+ stack[i] = this._makeTernary(cond, stack[i], saved[i]);
197398
+ }
197399
+ }
197400
+ } else if (stack.length > saved.length) {
197401
+ if (cond.type === PS_NODE.const) {
197402
+ if (!cond.value) {
197403
+ stack.length = 0;
197404
+ stack.push(...saved);
197405
+ }
197406
+ break;
197407
+ }
197408
+ const trueStack = stack.slice();
197409
+ this._evalBlockFrom(instructions, idx + 1, trueStack);
197410
+ if (this._failed) {
197411
+ break;
197412
+ }
197413
+ const falseStack = saved;
197414
+ this._evalBlockFrom(instructions, idx + 1, falseStack);
197415
+ if (this._failed) {
197416
+ break;
197417
+ }
197418
+ if (trueStack.length !== falseStack.length) {
197419
+ const zero222 = new PsConstNode(0);
197420
+ while (trueStack.length < falseStack.length) {
197421
+ trueStack.push(zero222);
197422
+ }
197423
+ while (falseStack.length < trueStack.length) {
197424
+ falseStack.push(zero222);
197425
+ }
197426
+ }
197427
+ stack.length = 0;
197428
+ for (let i = 0; i < trueStack.length; i++) {
197429
+ stack.push(this._makeTernary(cond, trueStack[i], falseStack[i]));
197430
+ }
197431
+ return;
197432
+ } else {
197433
+ this._failed = true;
197434
+ }
197435
+ break;
197436
+ }
197437
+ case PS_NODE.ifelse: {
197438
+ if (stack.length < 1) {
197439
+ this._failed = true;
197440
+ break;
197441
+ }
197442
+ const cond = stack.pop();
197443
+ const snapshot = stack.slice();
197444
+ const thenStack = snapshot.slice();
197445
+ this._evalBlock(instr.then, thenStack);
197446
+ if (this._failed) {
197447
+ break;
197448
+ }
197449
+ const elseStack = snapshot.slice();
197450
+ this._evalBlock(instr.otherwise, elseStack);
197451
+ if (this._failed) {
197452
+ break;
197453
+ }
197454
+ if (thenStack.length !== elseStack.length) {
197455
+ const zero222 = new PsConstNode(0);
197456
+ while (thenStack.length < elseStack.length) {
197457
+ thenStack.push(zero222);
197458
+ }
197459
+ while (elseStack.length < thenStack.length) {
197460
+ elseStack.push(zero222);
197461
+ }
197462
+ }
197463
+ stack.length = 0;
197464
+ for (let i = 0; i < thenStack.length; i++) {
197465
+ stack.push(this._makeTernary(cond, thenStack[i], elseStack[i]));
197466
+ }
197467
+ break;
197468
+ }
197469
+ }
197470
+ }
197471
+ }
197472
+ _evalOp(op, stack) {
197473
+ if (_PSStackToTree.#binaryOps.has(op)) {
197474
+ if (stack.length < 2) {
197475
+ this._failed = true;
197476
+ return;
197477
+ }
197478
+ const first = stack.pop();
197479
+ const second = stack.pop();
197480
+ stack.push(this._makeBinary(op, first, second));
197481
+ return;
197482
+ }
197483
+ if (_PSStackToTree.#unaryOps.has(op)) {
197484
+ if (stack.length < 1) {
197485
+ this._failed = true;
197486
+ return;
197487
+ }
197488
+ stack.push(this._makeUnary(op, stack.pop()));
197489
+ return;
197490
+ }
197491
+ switch (op) {
197492
+ case TOKEN.true:
197493
+ stack.push(new PsConstNode(true));
197494
+ if (stack.length > MAX_STACK_SIZE) {
197495
+ this._failed = true;
197496
+ }
197497
+ break;
197498
+ case TOKEN.false:
197499
+ stack.push(new PsConstNode(false));
197500
+ if (stack.length > MAX_STACK_SIZE) {
197501
+ this._failed = true;
197502
+ }
197503
+ break;
197504
+ case TOKEN.dup:
197505
+ if (stack.length < 1) {
197506
+ this._failed = true;
197507
+ break;
197508
+ }
197509
+ stack.push(stack.at(-1));
197510
+ if (stack.length > MAX_STACK_SIZE) {
197511
+ this._failed = true;
197512
+ }
197513
+ break;
197514
+ case TOKEN.exch: {
197515
+ if (stack.length < 2) {
197516
+ this._failed = true;
197517
+ break;
197518
+ }
197519
+ const a3 = stack.pop();
197520
+ const b3 = stack.pop();
197521
+ stack.push(a3, b3);
197522
+ break;
197523
+ }
197524
+ case TOKEN.pop:
197525
+ if (stack.length < 1) {
197526
+ this._failed = true;
197527
+ break;
197528
+ }
197529
+ stack.pop();
197530
+ break;
197531
+ case TOKEN.copy: {
197532
+ if (stack.length < 1) {
197533
+ this._failed = true;
197534
+ break;
197535
+ }
197536
+ const nNode = stack.pop();
197537
+ if (nNode.type === PS_NODE.const) {
197538
+ const n = nNode.value | 0;
197539
+ if (n === 0) {
197540
+ } else if (n < 0 || n > stack.length) {
197541
+ this._failed = true;
197542
+ } else {
197543
+ stack.push(...stack.slice(-n));
197544
+ if (stack.length > MAX_STACK_SIZE) {
197545
+ this._failed = true;
197546
+ }
197547
+ }
197548
+ } else {
197549
+ this._failed = true;
197550
+ }
197551
+ break;
197552
+ }
197553
+ case TOKEN.index: {
197554
+ if (stack.length < 1) {
197555
+ this._failed = true;
197556
+ break;
197557
+ }
197558
+ const nNode = stack.pop();
197559
+ if (nNode.type === PS_NODE.const) {
197560
+ const n = nNode.value | 0;
197561
+ if (n < 0 || n >= stack.length) {
197562
+ this._failed = true;
197563
+ } else {
197564
+ stack.push(stack.at(-n - 1));
197565
+ }
197566
+ } else {
197567
+ this._failed = true;
197568
+ }
197569
+ break;
197570
+ }
197571
+ case TOKEN.roll: {
197572
+ if (stack.length < 2) {
197573
+ this._failed = true;
197574
+ break;
197575
+ }
197576
+ const jNode = stack.pop();
197577
+ const nNode = stack.pop();
197578
+ if (nNode.type === PS_NODE.const && jNode.type === PS_NODE.const) {
197579
+ const n = nNode.value | 0;
197580
+ if (n === 0) {
197581
+ } else if (n < 0 || n > stack.length) {
197582
+ this._failed = true;
197583
+ } else {
197584
+ const j = ((jNode.value | 0) % n + n) % n;
197585
+ if (j > 0) {
197586
+ const slice = stack.splice(-n, n);
197587
+ stack.push(...slice.slice(n - j), ...slice.slice(0, n - j));
197588
+ }
197589
+ }
197590
+ } else {
197591
+ this._failed = true;
197592
+ }
197593
+ break;
197594
+ }
197595
+ default:
197596
+ this._failed = true;
197597
+ break;
197598
+ }
197599
+ }
197600
+ /**
197601
+ * Create a binary tree node, applying optimizations eagerly:
197602
+ *
197603
+ * 1. Constant folding — both operands are PsConstNode → fold to PsConstNode.
197604
+ * 2. Reflexive simplifications — x−x→0, x xor x→0, x eq x→true, etc.
197605
+ * 3. Algebraic simplifications with one known operand — identity elements
197606
+ * (x+0→x, x*1→x, …), absorbing elements (x*0→0, x and false→false, …),
197607
+ * and strength reductions (x*-1→neg(x), x^0.5→sqrt(x), x^2→x*x, …).
197608
+ *
197609
+ * Recall: `first` was on top of the stack (right operand for non-commutative
197610
+ * ops), `second` was below (left operand). So `a b sub` → second=a, first=b
197611
+ * → a − b.
197612
+ */
197613
+ _makeBinary(op, first, second) {
197614
+ if (first.type === PS_NODE.const && second.type === PS_NODE.const) {
197615
+ const v = _evalBinaryConst(op, second.value, first.value);
197616
+ if (v !== void 0) {
197617
+ return new PsConstNode(v);
197618
+ }
197619
+ }
197620
+ if (_nodesEqual(first, second)) {
197621
+ switch (op) {
197622
+ case TOKEN.sub:
197623
+ return new PsConstNode(0);
197624
+ // x − x → 0
197625
+ case TOKEN.xor:
197626
+ return new PsConstNode(
197627
+ /* eslint-disable unicorn/prefer-logical-operator-over-ternary */
197628
+ first.valueType === PS_VALUE_TYPE.boolean ? false : 0
197629
+ /* eslint-enable unicorn/prefer-logical-operator-over-ternary */
197630
+ );
197631
+ // TOKEN.mod, TOKEN.div, TOKEN.idiv are NOT simplified here:
197632
+ // x op x is undefined when x = 0, so we cannot fold without knowing
197633
+ // that x is non-zero.
197634
+ case TOKEN.and:
197635
+ case TOKEN.or:
197636
+ return first;
197637
+ // x and x → x; x or x → x
197638
+ case TOKEN.min:
197639
+ case TOKEN.max:
197640
+ return first;
197641
+ // min(x,x) → x; max(x,x) → x
197642
+ case TOKEN.eq:
197643
+ case TOKEN.ge:
197644
+ case TOKEN.le:
197645
+ return new PsConstNode(true);
197646
+ case TOKEN.ne:
197647
+ case TOKEN.gt:
197648
+ case TOKEN.lt:
197649
+ return new PsConstNode(false);
197650
+ }
197651
+ }
197652
+ if (first.type === PS_NODE.const) {
197653
+ const b3 = first.value;
197654
+ switch (op) {
197655
+ case TOKEN.add:
197656
+ if (b3 === 0) {
197657
+ return second;
197658
+ }
197659
+ break;
197660
+ case TOKEN.sub:
197661
+ if (b3 === 0) {
197662
+ return second;
197663
+ }
197664
+ break;
197665
+ case TOKEN.mul:
197666
+ if (b3 === 1) {
197667
+ return second;
197668
+ }
197669
+ if (b3 === 0) {
197670
+ return first;
197671
+ }
197672
+ if (b3 === -1) {
197673
+ return this._makeUnary(TOKEN.neg, second);
197674
+ }
197675
+ break;
197676
+ case TOKEN.div:
197677
+ if (b3 !== 0) {
197678
+ return this._makeBinary(TOKEN.mul, new PsConstNode(1 / b3), second);
197679
+ }
197680
+ break;
197681
+ case TOKEN.idiv:
197682
+ if (b3 === 1) {
197683
+ return second;
197684
+ }
197685
+ break;
197686
+ case TOKEN.exp:
197687
+ if (b3 === 1) {
197688
+ return second;
197689
+ }
197690
+ if (b3 === -1) {
197691
+ return this._makeBinary(TOKEN.div, second, new PsConstNode(1));
197692
+ }
197693
+ if (b3 === 0.5) {
197694
+ return this._makeUnary(TOKEN.sqrt, second);
197695
+ }
197696
+ if (b3 === 0.25) {
197697
+ const sqrtOnce = this._makeUnary(TOKEN.sqrt, second);
197698
+ return this._makeUnary(TOKEN.sqrt, sqrtOnce);
197699
+ }
197700
+ if (b3 === 2) {
197701
+ return this._makeBinary(TOKEN.mul, second, second);
197702
+ }
197703
+ if (b3 === 3) {
197704
+ return this._makeBinary(
197705
+ TOKEN.mul,
197706
+ this._makeBinary(TOKEN.mul, second, second),
197707
+ second
197708
+ );
197709
+ }
197710
+ if (b3 === 4) {
197711
+ const square2 = this._makeBinary(TOKEN.mul, second, second);
197712
+ return this._makeBinary(TOKEN.mul, square2, square2);
197713
+ }
197714
+ if (b3 === 0) {
197715
+ return new PsConstNode(1);
197716
+ }
197717
+ break;
197718
+ case TOKEN.and:
197719
+ if (b3 === true) {
197720
+ return second;
197721
+ }
197722
+ if (b3 === false) {
197723
+ return first;
197724
+ }
197725
+ break;
197726
+ case TOKEN.or:
197727
+ if (b3 === false) {
197728
+ return second;
197729
+ }
197730
+ if (b3 === true) {
197731
+ return first;
197732
+ }
197733
+ break;
197734
+ case TOKEN.min:
197735
+ if (second.type === PS_NODE.binary && second.op === TOKEN.max && second.first.type === PS_NODE.const && second.first.value >= b3) {
197736
+ return first;
197737
+ }
197738
+ break;
197739
+ case TOKEN.max:
197740
+ if (second.type === PS_NODE.binary && second.op === TOKEN.min && second.first.type === PS_NODE.const && second.first.value <= b3) {
197741
+ return first;
197742
+ }
197743
+ break;
197744
+ }
197745
+ }
197746
+ if (second.type === PS_NODE.const) {
197747
+ const a3 = second.value;
197748
+ switch (op) {
197749
+ case TOKEN.add:
197750
+ if (a3 === 0) {
197751
+ return first;
197752
+ }
197753
+ break;
197754
+ case TOKEN.sub:
197755
+ if (a3 === 0) {
197756
+ return this._makeUnary(TOKEN.neg, first);
197757
+ }
197758
+ break;
197759
+ case TOKEN.mul:
197760
+ if (a3 === 1) {
197761
+ return first;
197762
+ }
197763
+ if (a3 === 0) {
197764
+ return second;
197765
+ }
197766
+ if (a3 === -1) {
197767
+ return this._makeUnary(TOKEN.neg, first);
197768
+ }
197769
+ break;
197770
+ case TOKEN.and:
197771
+ if (a3 === true) {
197772
+ return first;
197773
+ }
197774
+ if (a3 === false) {
197775
+ return second;
197776
+ }
197777
+ break;
197778
+ case TOKEN.or:
197779
+ if (a3 === false) {
197780
+ return first;
197781
+ }
197782
+ if (a3 === true) {
197783
+ return second;
197784
+ }
197785
+ break;
197786
+ }
197787
+ }
197788
+ return new PsBinaryNode(
197789
+ op,
197790
+ first,
197791
+ second,
197792
+ _binaryValueType(op, first.valueType, second.valueType)
197793
+ );
197794
+ }
197795
+ /**
197796
+ * Create a unary tree node, applying optimizations eagerly:
197797
+ *
197798
+ * 1. Constant folding.
197799
+ * 2. not(comparison) → negated comparison: not(a eq b) → a ne b, etc.
197800
+ * 3. neg(a − b) → b − a.
197801
+ * 4. Double-negation: neg(neg(x)) → x, not(not(x)) → x.
197802
+ * 5. abs(neg(x)) → abs(x).
197803
+ * 6. Idempotent: f(f(x)) → f(x) for abs, ceiling, floor, round, etc.
197804
+ */
197805
+ _makeUnary(op, operand) {
197806
+ if (operand.type === PS_NODE.const) {
197807
+ const v = _evalUnaryConst(op, operand.value);
197808
+ if (v !== void 0) {
197809
+ return new PsConstNode(v);
197810
+ }
197811
+ }
197812
+ if (op === TOKEN.not && operand.type === PS_NODE.binary) {
197813
+ const negated = _PSStackToTree.#negatedComparison.get(operand.op);
197814
+ if (negated !== void 0) {
197815
+ return new PsBinaryNode(
197816
+ negated,
197817
+ operand.first,
197818
+ operand.second,
197819
+ PS_VALUE_TYPE.boolean
197820
+ );
197821
+ }
197822
+ }
197823
+ if (op === TOKEN.neg && operand.type === PS_NODE.binary && operand.op === TOKEN.sub) {
197824
+ return this._makeBinary(TOKEN.sub, operand.second, operand.first);
197825
+ }
197826
+ if (operand.type === PS_NODE.unary) {
197827
+ if (op === TOKEN.neg && operand.op === TOKEN.neg || op === TOKEN.not && operand.op === TOKEN.not) {
197828
+ return operand.operand;
197829
+ }
197830
+ if (op === TOKEN.abs && operand.op === TOKEN.neg) {
197831
+ return this._makeUnary(TOKEN.abs, operand.operand);
197832
+ }
197833
+ if (_PSStackToTree.#idempotentUnary.has(op) && op === operand.op) {
197834
+ return operand;
197835
+ }
197836
+ }
197837
+ return new PsUnaryNode(op, operand, _unaryValueType(op, operand.valueType));
197838
+ }
197839
+ /**
197840
+ * Create a ternary node, applying optimizations eagerly:
197841
+ *
197842
+ * 1. Constant condition — fold to the live branch.
197843
+ * 2. Identical branches — the condition is irrelevant, return either branch.
197844
+ * 3. Boolean branch constants — `cond ? true : false` → cond,
197845
+ * `cond ? false : true` → not(cond).
197846
+ * 4. Ternary → branchless min/max when the condition compares two numeric
197847
+ * expressions that are also the two branches.
197848
+ */
197849
+ _makeTernary(cond, then, otherwise) {
197850
+ if (cond.type === PS_NODE.const) {
197851
+ return cond.value ? then : otherwise;
197852
+ }
197853
+ if (_nodesEqual(then, otherwise)) {
197854
+ return then;
197855
+ }
197856
+ if (then.type === PS_NODE.const && otherwise.type === PS_NODE.const) {
197857
+ if (then.value === true && otherwise.value === false) {
197858
+ return cond;
197859
+ }
197860
+ if (then.value === false && otherwise.value === true) {
197861
+ return this._makeUnary(TOKEN.not, cond);
197862
+ }
197863
+ }
197864
+ if (cond.type === PS_NODE.binary) {
197865
+ const { op: cop, first: cf, second: cs } = cond;
197866
+ if (cop === TOKEN.gt || cop === TOKEN.ge) {
197867
+ if (_nodesEqual(then, cf) && _nodesEqual(otherwise, cs)) {
197868
+ return this._makeBinary(TOKEN.min, cf, cs);
197869
+ }
197870
+ if (_nodesEqual(then, cs) && _nodesEqual(otherwise, cf)) {
197871
+ return this._makeBinary(TOKEN.max, cf, cs);
197872
+ }
197873
+ } else if (cop === TOKEN.lt || cop === TOKEN.le) {
197874
+ if (_nodesEqual(then, cf) && _nodesEqual(otherwise, cs)) {
197875
+ return this._makeBinary(TOKEN.max, cf, cs);
197876
+ }
197877
+ if (_nodesEqual(then, cs) && _nodesEqual(otherwise, cf)) {
197878
+ return this._makeBinary(TOKEN.min, cf, cs);
197879
+ }
197880
+ }
197881
+ }
197882
+ return new PsTernaryNode(
197883
+ cond,
197884
+ then,
197885
+ otherwise,
197886
+ then.valueType === otherwise.valueType ? then.valueType : PS_VALUE_TYPE.unknown
197887
+ );
197888
+ }
197889
+ };
197890
+ var OP = {
197891
+ ARG: 0,
197892
+ // [ARG, idx]
197893
+ CONST: 1,
197894
+ // [CONST, val]
197895
+ STORE: 2,
197896
+ // [STORE, slot, min, max] clamp(pop()) → mem[slot]
197897
+ IF: 3,
197898
+ // [IF, target] jump when top-of-stack === 0
197899
+ JUMP: 4,
197900
+ // [JUMP, target] unconditional
197901
+ ABS: 5,
197902
+ NEG: 6,
197903
+ CEIL: 7,
197904
+ FLOOR: 8,
197905
+ ROUND: 9,
197906
+ // floor(x + 0.5)
197907
+ TRUNC: 10,
197908
+ NOT_B: 11,
197909
+ // boolean NOT
197910
+ NOT_N: 12,
197911
+ // bitwise NOT
197912
+ SQRT: 13,
197913
+ SIN: 14,
197914
+ // degrees in/out
197915
+ COS: 15,
197916
+ LN: 16,
197917
+ LOG10: 17,
197918
+ CVI: 18,
197919
+ SHIFT: 19,
197920
+ // [SHIFT, amount] +ve = left, −ve = right
197921
+ // Binary ops: second below, first on top; result = second OP first.
197922
+ ADD: 20,
197923
+ SUB: 21,
197924
+ MUL: 22,
197925
+ DIV: 23,
197926
+ // 0 when divisor is 0
197927
+ IDIV: 24,
197928
+ // 0 when divisor is 0
197929
+ MOD: 25,
197930
+ // 0 when divisor is 0
197931
+ POW: 26,
197932
+ EQ: 27,
197933
+ NE: 28,
197934
+ GT: 29,
197935
+ GE: 30,
197936
+ LT: 31,
197937
+ LE: 32,
197938
+ AND: 33,
197939
+ OR: 34,
197940
+ XOR: 35,
197941
+ ATAN: 36,
197942
+ // atan2(second, first) → degrees [0, 360)
197943
+ MIN: 37,
197944
+ MAX: 38,
197945
+ TEE_TMP: 39,
197946
+ // [TEE_TMP, slot] peek top of stack → tmp[slot], leave on stack
197947
+ LOAD_TMP: 40
197948
+ // [LOAD_TMP, slot] push tmp[slot]
197949
+ };
197950
+ var _DEG_TO_RAD = Math.PI / 180;
197951
+ var _RAD_TO_DEG = 180 / Math.PI;
197952
+ var PsJsCompiler = class {
197953
+ // Safe because JS is single-threaded.
197954
+ static #stack = new Float64Array(64);
197955
+ static #tmp = new Float64Array(64);
197956
+ constructor(domain, range3) {
197957
+ this.nIn = domain.length >> 1;
197958
+ this.nOut = range3.length >> 1;
197959
+ this.range = range3;
197960
+ this.ir = [];
197961
+ this._tmpMap = /* @__PURE__ */ new Map();
197962
+ this._nextTmp = 0;
197963
+ }
197964
+ _compileNode(node3) {
197965
+ if (node3.shared) {
197966
+ const cached = this._tmpMap.get(node3);
197967
+ if (cached !== void 0) {
197968
+ this.ir.push(OP.LOAD_TMP, cached);
197969
+ return true;
197970
+ }
197971
+ if (!this._compileNodeImpl(node3)) {
197972
+ return false;
197973
+ }
197974
+ const slot = this._nextTmp++;
197975
+ this._tmpMap.set(node3, slot);
197976
+ this.ir.push(OP.TEE_TMP, slot);
197977
+ return true;
197978
+ }
197979
+ return this._compileNodeImpl(node3);
197980
+ }
197981
+ _compileNodeImpl(node3) {
197982
+ switch (node3.type) {
197983
+ case PS_NODE.arg:
197984
+ this.ir.push(OP.ARG, node3.index);
197985
+ return true;
197986
+ case PS_NODE.const: {
197987
+ const v = node3.value;
197988
+ this.ir.push(OP.CONST, typeof v === "boolean" ? Number(v) : v);
197989
+ return true;
197990
+ }
197991
+ case PS_NODE.unary:
197992
+ return this._compileUnary(node3);
197993
+ case PS_NODE.binary:
197994
+ return this._compileBinary(node3);
197995
+ case PS_NODE.ternary:
197996
+ return this._compileTernary(node3);
197997
+ default:
197998
+ return false;
197999
+ }
198000
+ }
198001
+ _compileUnary(node3) {
198002
+ const { op, operand, valueType } = node3;
198003
+ if (op === TOKEN.cvr) {
198004
+ return this._compileNode(operand);
198005
+ }
198006
+ if (!this._compileNode(operand)) {
198007
+ return false;
198008
+ }
198009
+ switch (op) {
198010
+ case TOKEN.abs:
198011
+ this.ir.push(OP.ABS);
198012
+ break;
198013
+ case TOKEN.neg:
198014
+ this.ir.push(OP.NEG);
198015
+ break;
198016
+ case TOKEN.ceiling:
198017
+ this.ir.push(OP.CEIL);
198018
+ break;
198019
+ case TOKEN.floor:
198020
+ this.ir.push(OP.FLOOR);
198021
+ break;
198022
+ case TOKEN.round:
198023
+ this.ir.push(OP.ROUND);
198024
+ break;
198025
+ case TOKEN.truncate:
198026
+ this.ir.push(OP.TRUNC);
198027
+ break;
198028
+ case TOKEN.sqrt:
198029
+ this.ir.push(OP.SQRT);
198030
+ break;
198031
+ case TOKEN.sin:
198032
+ this.ir.push(OP.SIN);
198033
+ break;
198034
+ case TOKEN.cos:
198035
+ this.ir.push(OP.COS);
198036
+ break;
198037
+ case TOKEN.ln:
198038
+ this.ir.push(OP.LN);
198039
+ break;
198040
+ case TOKEN.log:
198041
+ this.ir.push(OP.LOG10);
198042
+ break;
198043
+ case TOKEN.cvi:
198044
+ this.ir.push(OP.CVI);
198045
+ break;
198046
+ case TOKEN.not:
198047
+ if (valueType === PS_VALUE_TYPE.boolean) {
198048
+ this.ir.push(OP.NOT_B);
198049
+ } else if (valueType === PS_VALUE_TYPE.numeric) {
198050
+ this.ir.push(OP.NOT_N);
198051
+ } else {
198052
+ return false;
198053
+ }
198054
+ break;
198055
+ default:
198056
+ return false;
198057
+ }
198058
+ return true;
198059
+ }
198060
+ _compileBinary(node3) {
198061
+ const { op, first, second } = node3;
198062
+ if (op === TOKEN.bitshift) {
198063
+ if (first.type !== PS_NODE.const || !Number.isInteger(first.value) || !this._compileNode(second)) {
198064
+ return false;
198065
+ }
198066
+ this.ir.push(OP.SHIFT, first.value);
198067
+ return true;
198068
+ }
198069
+ if (!this._compileNode(second) || !this._compileNode(first)) {
198070
+ return false;
198071
+ }
198072
+ switch (op) {
198073
+ case TOKEN.add:
198074
+ this.ir.push(OP.ADD);
198075
+ break;
198076
+ case TOKEN.sub:
198077
+ this.ir.push(OP.SUB);
198078
+ break;
198079
+ case TOKEN.mul:
198080
+ this.ir.push(OP.MUL);
198081
+ break;
198082
+ case TOKEN.div:
198083
+ this.ir.push(OP.DIV);
198084
+ break;
198085
+ case TOKEN.idiv:
198086
+ this.ir.push(OP.IDIV);
198087
+ break;
198088
+ case TOKEN.mod:
198089
+ this.ir.push(OP.MOD);
198090
+ break;
198091
+ case TOKEN.exp:
198092
+ this.ir.push(OP.POW);
198093
+ break;
198094
+ case TOKEN.eq:
198095
+ this.ir.push(OP.EQ);
198096
+ break;
198097
+ case TOKEN.ne:
198098
+ this.ir.push(OP.NE);
198099
+ break;
198100
+ case TOKEN.gt:
198101
+ this.ir.push(OP.GT);
198102
+ break;
198103
+ case TOKEN.ge:
198104
+ this.ir.push(OP.GE);
198105
+ break;
198106
+ case TOKEN.lt:
198107
+ this.ir.push(OP.LT);
198108
+ break;
198109
+ case TOKEN.le:
198110
+ this.ir.push(OP.LE);
198111
+ break;
198112
+ case TOKEN.and:
198113
+ this.ir.push(OP.AND);
198114
+ break;
198115
+ case TOKEN.or:
198116
+ this.ir.push(OP.OR);
198117
+ break;
198118
+ case TOKEN.xor:
198119
+ this.ir.push(OP.XOR);
198120
+ break;
198121
+ case TOKEN.atan:
198122
+ this.ir.push(OP.ATAN);
198123
+ break;
198124
+ case TOKEN.min:
198125
+ this.ir.push(OP.MIN);
198126
+ break;
198127
+ case TOKEN.max:
198128
+ this.ir.push(OP.MAX);
198129
+ break;
198130
+ default:
198131
+ return false;
198132
+ }
198133
+ return true;
198134
+ }
198135
+ _compileTernary(node3) {
198136
+ if (!this._compileNode(node3.cond)) {
198137
+ return false;
198138
+ }
198139
+ this.ir.push(OP.IF, 0);
198140
+ const ifPatch = this.ir.length - 1;
198141
+ if (!this._compileNode(node3.then)) {
198142
+ return false;
198143
+ }
198144
+ this.ir.push(OP.JUMP, 0);
198145
+ const jumpPatch = this.ir.length - 1;
198146
+ this.ir[ifPatch] = this.ir.length;
198147
+ if (!this._compileNode(node3.otherwise)) {
198148
+ return false;
198149
+ }
198150
+ this.ir[jumpPatch] = this.ir.length;
198151
+ return true;
198152
+ }
198153
+ compile(program) {
198154
+ const outputs = new PSStackToTree().evaluate(program, this.nIn);
198155
+ if (!outputs || outputs.length < this.nOut) {
198156
+ return null;
198157
+ }
198158
+ for (let i = 0; i < this.nOut; i++) {
198159
+ if (!this._compileNode(outputs[i])) {
198160
+ return null;
198161
+ }
198162
+ const min = this.range[i * 2];
198163
+ const max = this.range[i * 2 + 1];
198164
+ this.ir.push(OP.STORE, i, min, max);
198165
+ }
198166
+ return new Float64Array(this.ir);
198167
+ }
198168
+ static execute(ir, src, srcOffset, dest, destOffset) {
198169
+ let ip = 0, sp = 0;
198170
+ const n = ir.length;
198171
+ const stack = this.#stack;
198172
+ const tmp = this.#tmp;
198173
+ while (ip < n) {
198174
+ switch (ir[ip++] | 0) {
198175
+ case OP.ARG:
198176
+ stack[sp++] = src[srcOffset + (ir[ip++] | 0)];
198177
+ break;
198178
+ case OP.CONST:
198179
+ stack[sp++] = ir[ip++];
198180
+ break;
198181
+ case OP.STORE: {
198182
+ const slot = ir[ip++] | 0;
198183
+ const min = ir[ip++];
198184
+ const max = ir[ip++];
198185
+ dest[destOffset + slot] = MathClamp(stack[--sp], min, max);
198186
+ break;
198187
+ }
198188
+ case OP.IF: {
198189
+ const tgt = ir[ip++];
198190
+ if (stack[--sp] === 0) {
198191
+ ip = tgt;
198192
+ }
198193
+ break;
198194
+ }
198195
+ case OP.JUMP:
198196
+ ip = ir[ip];
198197
+ break;
198198
+ case OP.ABS:
198199
+ stack[sp - 1] = Math.abs(stack[sp - 1]);
198200
+ break;
198201
+ case OP.NEG:
198202
+ stack[sp - 1] = -stack[sp - 1];
198203
+ break;
198204
+ case OP.CEIL:
198205
+ stack[sp - 1] = Math.ceil(stack[sp - 1]);
198206
+ break;
198207
+ case OP.FLOOR:
198208
+ stack[sp - 1] = Math.floor(stack[sp - 1]);
198209
+ break;
198210
+ case OP.ROUND:
198211
+ stack[sp - 1] = Math.floor(stack[sp - 1] + 0.5);
198212
+ break;
198213
+ case OP.TRUNC:
198214
+ stack[sp - 1] = Math.trunc(stack[sp - 1]);
198215
+ break;
198216
+ case OP.NOT_B:
198217
+ stack[sp - 1] = stack[sp - 1] !== 0 ? 0 : 1;
198218
+ break;
198219
+ case OP.NOT_N:
198220
+ stack[sp - 1] = ~(stack[sp - 1] | 0);
198221
+ break;
198222
+ case OP.SQRT:
198223
+ stack[sp - 1] = Math.sqrt(stack[sp - 1]);
198224
+ break;
198225
+ case OP.SIN:
198226
+ stack[sp - 1] = Math.sin(stack[sp - 1] % 360 * _DEG_TO_RAD);
198227
+ break;
198228
+ case OP.COS:
198229
+ stack[sp - 1] = Math.cos(stack[sp - 1] % 360 * _DEG_TO_RAD);
198230
+ break;
198231
+ case OP.LN:
198232
+ stack[sp - 1] = Math.log(stack[sp - 1]);
198233
+ break;
198234
+ case OP.LOG10:
198235
+ stack[sp - 1] = Math.log10(stack[sp - 1]);
198236
+ break;
198237
+ case OP.CVI:
198238
+ stack[sp - 1] = Math.trunc(stack[sp - 1]) | 0;
198239
+ break;
198240
+ case OP.SHIFT: {
198241
+ const amt = ir[ip++];
198242
+ const v = stack[sp - 1] | 0;
198243
+ if (amt > 0) {
198244
+ stack[sp - 1] = v << amt;
198245
+ } else if (amt < 0) {
198246
+ stack[sp - 1] = v >> -amt;
198247
+ } else {
198248
+ stack[sp - 1] = v;
198249
+ }
198250
+ break;
198251
+ }
198252
+ case OP.ADD: {
198253
+ const b3 = stack[--sp];
198254
+ stack[sp - 1] += b3;
198255
+ break;
198256
+ }
198257
+ case OP.SUB: {
198258
+ const b3 = stack[--sp];
198259
+ stack[sp - 1] -= b3;
198260
+ break;
198261
+ }
198262
+ case OP.MUL: {
198263
+ const b3 = stack[--sp];
198264
+ stack[sp - 1] *= b3;
198265
+ break;
198266
+ }
198267
+ case OP.DIV: {
198268
+ const b3 = stack[--sp];
198269
+ stack[sp - 1] = b3 !== 0 ? stack[sp - 1] / b3 : 0;
198270
+ break;
198271
+ }
198272
+ case OP.IDIV: {
198273
+ const b3 = stack[--sp];
198274
+ stack[sp - 1] = b3 !== 0 ? Math.trunc(stack[sp - 1] / b3) : 0;
198275
+ break;
198276
+ }
198277
+ case OP.MOD: {
198278
+ const b3 = stack[--sp];
198279
+ stack[sp - 1] = b3 !== 0 ? stack[sp - 1] % b3 : 0;
198280
+ break;
198281
+ }
198282
+ case OP.POW: {
198283
+ const b3 = stack[--sp];
198284
+ stack[sp - 1] **= b3;
198285
+ break;
198286
+ }
198287
+ case OP.EQ: {
198288
+ const b3 = stack[--sp];
198289
+ stack[sp - 1] = stack[sp - 1] === b3 ? 1 : 0;
198290
+ break;
198291
+ }
198292
+ case OP.NE: {
198293
+ const b3 = stack[--sp];
198294
+ stack[sp - 1] = stack[sp - 1] !== b3 ? 1 : 0;
198295
+ break;
198296
+ }
198297
+ case OP.GT: {
198298
+ const b3 = stack[--sp];
198299
+ stack[sp - 1] = stack[sp - 1] > b3 ? 1 : 0;
198300
+ break;
198301
+ }
198302
+ case OP.GE: {
198303
+ const b3 = stack[--sp];
198304
+ stack[sp - 1] = stack[sp - 1] >= b3 ? 1 : 0;
198305
+ break;
198306
+ }
198307
+ case OP.LT: {
198308
+ const b3 = stack[--sp];
198309
+ stack[sp - 1] = stack[sp - 1] < b3 ? 1 : 0;
198310
+ break;
198311
+ }
198312
+ case OP.LE: {
198313
+ const b3 = stack[--sp];
198314
+ stack[sp - 1] = stack[sp - 1] <= b3 ? 1 : 0;
198315
+ break;
198316
+ }
198317
+ case OP.AND: {
198318
+ const b3 = stack[--sp] | 0;
198319
+ stack[sp - 1] = (stack[sp - 1] | 0) & b3;
198320
+ break;
198321
+ }
198322
+ case OP.OR: {
198323
+ const b3 = stack[--sp] | 0;
198324
+ stack[sp - 1] = stack[sp - 1] | 0 | b3;
198325
+ break;
198326
+ }
198327
+ case OP.XOR: {
198328
+ const b3 = stack[--sp] | 0;
198329
+ stack[sp - 1] = (stack[sp - 1] | 0) ^ b3;
198330
+ break;
198331
+ }
198332
+ case OP.ATAN: {
198333
+ const b3 = stack[--sp];
198334
+ const deg = Math.atan2(stack[sp - 1], b3) * _RAD_TO_DEG;
198335
+ stack[sp - 1] = deg < 0 ? deg + 360 : deg;
198336
+ break;
198337
+ }
198338
+ case OP.MIN: {
198339
+ const b3 = stack[--sp];
198340
+ stack[sp - 1] = Math.min(stack[sp - 1], b3);
198341
+ break;
198342
+ }
198343
+ case OP.MAX: {
198344
+ const b3 = stack[--sp];
198345
+ stack[sp - 1] = Math.max(stack[sp - 1], b3);
198346
+ break;
198347
+ }
198348
+ case OP.TEE_TMP:
198349
+ tmp[ir[ip++] | 0] = stack[sp - 1];
198350
+ break;
198351
+ case OP.LOAD_TMP:
198352
+ stack[sp++] = tmp[ir[ip++] | 0];
198353
+ break;
198354
+ }
198355
+ }
198356
+ }
198357
+ };
198358
+ var PSStackBasedInterpreter = class {
198359
+ // Safe: JS is single-threaded.
198360
+ static #stack = new Float64Array(100);
198361
+ static #sp = 0;
198362
+ static #push(v) {
198363
+ if (this.#sp < this.#stack.length) {
198364
+ this.#stack[this.#sp++] = v;
198365
+ }
198366
+ }
198367
+ static #execOp(op) {
198368
+ const stack = this.#stack;
198369
+ switch (op) {
198370
+ case TOKEN.true:
198371
+ this.#push(1);
198372
+ break;
198373
+ case TOKEN.false:
198374
+ this.#push(0);
198375
+ break;
198376
+ case TOKEN.abs:
198377
+ stack[this.#sp - 1] = Math.abs(stack[this.#sp - 1]);
198378
+ break;
198379
+ case TOKEN.neg:
198380
+ stack[this.#sp - 1] = -stack[this.#sp - 1];
198381
+ break;
198382
+ case TOKEN.ceiling:
198383
+ stack[this.#sp - 1] = Math.ceil(stack[this.#sp - 1]);
198384
+ break;
198385
+ case TOKEN.floor:
198386
+ stack[this.#sp - 1] = Math.floor(stack[this.#sp - 1]);
198387
+ break;
198388
+ case TOKEN.round:
198389
+ stack[this.#sp - 1] = Math.floor(stack[this.#sp - 1] + 0.5);
198390
+ break;
198391
+ case TOKEN.truncate:
198392
+ stack[this.#sp - 1] = Math.trunc(stack[this.#sp - 1]);
198393
+ break;
198394
+ case TOKEN.sqrt:
198395
+ stack[this.#sp - 1] = Math.sqrt(stack[this.#sp - 1]);
198396
+ break;
198397
+ case TOKEN.sin:
198398
+ stack[this.#sp - 1] = Math.sin(
198399
+ stack[this.#sp - 1] % 360 * _DEG_TO_RAD
198400
+ );
198401
+ break;
198402
+ case TOKEN.cos:
198403
+ stack[this.#sp - 1] = Math.cos(
198404
+ stack[this.#sp - 1] % 360 * _DEG_TO_RAD
198405
+ );
198406
+ break;
198407
+ case TOKEN.ln:
198408
+ stack[this.#sp - 1] = Math.log(stack[this.#sp - 1]);
198409
+ break;
198410
+ case TOKEN.log:
198411
+ stack[this.#sp - 1] = Math.log10(stack[this.#sp - 1]);
198412
+ break;
198413
+ case TOKEN.cvi:
198414
+ stack[this.#sp - 1] = Math.trunc(stack[this.#sp - 1]) | 0;
198415
+ break;
198416
+ case TOKEN.cvr:
198417
+ break;
198418
+ // values are already f64
198419
+ case TOKEN.not: {
198420
+ const v = stack[this.#sp - 1];
198421
+ stack[this.#sp - 1] = v === 0 || v === 1 ? 1 - v : ~(v | 0);
198422
+ break;
198423
+ }
198424
+ case TOKEN.add: {
198425
+ const b3 = stack[--this.#sp];
198426
+ stack[this.#sp - 1] += b3;
198427
+ break;
198428
+ }
198429
+ case TOKEN.sub: {
198430
+ const b3 = stack[--this.#sp];
198431
+ stack[this.#sp - 1] -= b3;
198432
+ break;
198433
+ }
198434
+ case TOKEN.mul: {
198435
+ const b3 = stack[--this.#sp];
198436
+ stack[this.#sp - 1] *= b3;
198437
+ break;
198438
+ }
198439
+ case TOKEN.div: {
198440
+ const b3 = stack[--this.#sp];
198441
+ stack[this.#sp - 1] = b3 !== 0 ? stack[this.#sp - 1] / b3 : 0;
198442
+ break;
198443
+ }
198444
+ case TOKEN.idiv: {
198445
+ const b3 = stack[--this.#sp];
198446
+ stack[this.#sp - 1] = b3 !== 0 ? Math.trunc(stack[this.#sp - 1] / b3) : 0;
198447
+ break;
198448
+ }
198449
+ case TOKEN.mod: {
198450
+ const b3 = stack[--this.#sp];
198451
+ stack[this.#sp - 1] = b3 !== 0 ? stack[this.#sp - 1] % b3 : 0;
198452
+ break;
198453
+ }
198454
+ case TOKEN.exp: {
198455
+ const b3 = stack[--this.#sp];
198456
+ stack[this.#sp - 1] **= b3;
198457
+ break;
198458
+ }
198459
+ case TOKEN.atan: {
198460
+ const dx = stack[--this.#sp];
198461
+ const deg = Math.atan2(stack[this.#sp - 1], dx) * _RAD_TO_DEG;
198462
+ stack[this.#sp - 1] = deg < 0 ? deg + 360 : deg;
198463
+ break;
198464
+ }
198465
+ case TOKEN.eq: {
198466
+ const b3 = stack[--this.#sp];
198467
+ stack[this.#sp - 1] = stack[this.#sp - 1] === b3 ? 1 : 0;
198468
+ break;
198469
+ }
198470
+ case TOKEN.ne: {
198471
+ const b3 = stack[--this.#sp];
198472
+ stack[this.#sp - 1] = stack[this.#sp - 1] !== b3 ? 1 : 0;
198473
+ break;
198474
+ }
198475
+ case TOKEN.gt: {
198476
+ const b3 = stack[--this.#sp];
198477
+ stack[this.#sp - 1] = stack[this.#sp - 1] > b3 ? 1 : 0;
198478
+ break;
198479
+ }
198480
+ case TOKEN.ge: {
198481
+ const b3 = stack[--this.#sp];
198482
+ stack[this.#sp - 1] = stack[this.#sp - 1] >= b3 ? 1 : 0;
198483
+ break;
198484
+ }
198485
+ case TOKEN.lt: {
198486
+ const b3 = stack[--this.#sp];
198487
+ stack[this.#sp - 1] = stack[this.#sp - 1] < b3 ? 1 : 0;
198488
+ break;
198489
+ }
198490
+ case TOKEN.le: {
198491
+ const b3 = stack[--this.#sp];
198492
+ stack[this.#sp - 1] = stack[this.#sp - 1] <= b3 ? 1 : 0;
198493
+ break;
198494
+ }
198495
+ case TOKEN.and: {
198496
+ const b3 = stack[--this.#sp] | 0;
198497
+ stack[this.#sp - 1] = (stack[this.#sp - 1] | 0) & b3;
198498
+ break;
198499
+ }
198500
+ case TOKEN.or: {
198501
+ const b3 = stack[--this.#sp] | 0;
198502
+ stack[this.#sp - 1] = stack[this.#sp - 1] | 0 | b3;
198503
+ break;
198504
+ }
198505
+ case TOKEN.xor: {
198506
+ const b3 = stack[--this.#sp] | 0;
198507
+ stack[this.#sp - 1] = (stack[this.#sp - 1] | 0) ^ b3;
198508
+ break;
198509
+ }
198510
+ case TOKEN.bitshift: {
198511
+ const amt = stack[--this.#sp] | 0;
198512
+ const v = stack[this.#sp - 1] | 0;
198513
+ stack[this.#sp - 1] = amt > 0 ? v << amt : v >> -amt;
198514
+ break;
198515
+ }
198516
+ case TOKEN.min: {
198517
+ const b3 = stack[--this.#sp];
198518
+ stack[this.#sp - 1] = Math.min(stack[this.#sp - 1], b3);
198519
+ break;
198520
+ }
198521
+ case TOKEN.max: {
198522
+ const b3 = stack[--this.#sp];
198523
+ stack[this.#sp - 1] = Math.max(stack[this.#sp - 1], b3);
198524
+ break;
198525
+ }
198526
+ case TOKEN.dup:
198527
+ this.#push(stack[this.#sp - 1]);
198528
+ break;
198529
+ case TOKEN.exch: {
198530
+ const a3 = stack[--this.#sp];
198531
+ const b3 = stack[--this.#sp];
198532
+ this.#push(a3);
198533
+ this.#push(b3);
198534
+ break;
198535
+ }
198536
+ case TOKEN.pop:
198537
+ this.#sp--;
198538
+ break;
198539
+ case TOKEN.copy: {
198540
+ const n = Math.trunc(stack[--this.#sp]);
198541
+ const base = this.#sp - n;
198542
+ for (let k = 0; k < n; k++) {
198543
+ this.#push(stack[base + k]);
198544
+ }
198545
+ break;
198546
+ }
198547
+ case TOKEN.index: {
198548
+ const i = Math.trunc(stack[--this.#sp]);
198549
+ this.#push(stack[this.#sp - 1 - i]);
198550
+ break;
198551
+ }
198552
+ case TOKEN.roll: {
198553
+ const j = Math.trunc(stack[--this.#sp]);
198554
+ const n = Math.trunc(stack[--this.#sp]);
198555
+ if (n > 1 && j !== 0) {
198556
+ const mod = (j % n + n) % n;
198557
+ if (mod !== 0) {
198558
+ const base = this.#sp - n;
198559
+ const sub = stack.slice(base, this.#sp);
198560
+ for (let k = 0; k < n; k++) {
198561
+ stack[base + k] = sub[(k - mod + n) % n];
198562
+ }
198563
+ }
198564
+ }
198565
+ break;
198566
+ }
198567
+ }
198568
+ }
198569
+ static #execBlock(instructions) {
198570
+ for (const instr of instructions) {
198571
+ switch (instr.type) {
198572
+ case PS_NODE.number:
198573
+ this.#push(instr.value);
198574
+ break;
198575
+ case PS_NODE.operator:
198576
+ this.#execOp(instr.op);
198577
+ break;
198578
+ case PS_NODE.if:
198579
+ if (this.#stack[--this.#sp] !== 0) {
198580
+ this.#execBlock(instr.then.instructions);
198581
+ }
198582
+ break;
198583
+ case PS_NODE.ifelse:
198584
+ if (this.#stack[--this.#sp] !== 0) {
198585
+ this.#execBlock(instr.then.instructions);
198586
+ } else {
198587
+ this.#execBlock(instr.otherwise.instructions);
198588
+ }
198589
+ break;
198590
+ }
198591
+ }
198592
+ }
198593
+ /**
198594
+ * @param {import("./ast.js").PsProgram} program
198595
+ * @param {number[]} domain – flat [min0,max0, …]
198596
+ * @param {number[]} range – flat [min0,max0, …]
198597
+ * @returns {Function} – `(src, srcOffset, dest, destOffset) => void`
198598
+ */
198599
+ static build(program, domain, range3) {
198600
+ const nIn = domain.length >> 1;
198601
+ const nOut = range3.length >> 1;
198602
+ const { instructions } = program.body;
198603
+ return (src, srcOffset, dest, destOffset) => {
198604
+ this.#sp = 0;
198605
+ for (let i = 0; i < nIn; i++) {
198606
+ this.#push(src[srcOffset + i]);
198607
+ }
198608
+ this.#execBlock(instructions);
198609
+ const base = this.#sp - nOut;
198610
+ for (let i = 0; i < nOut; i++) {
198611
+ const v = base + i >= 0 ? this.#stack[base + i] : 0;
198612
+ dest[destOffset + i] = MathClamp(v, range3[i * 2], range3[i * 2 + 1]);
198613
+ }
198614
+ };
198615
+ }
198616
+ };
198617
+ function buildPostScriptJsFunction(source, domain, range3, forceInterpreter = false) {
198618
+ const program = parsePostScriptFunction(source);
198619
+ const ir = !forceInterpreter && new PsJsCompiler(domain, range3).compile(program);
198620
+ if (ir) {
198621
+ return (src, srcOffset, dest, destOffset) => {
198622
+ PsJsCompiler.execute(ir, src, srcOffset, dest, destOffset);
198623
+ };
198624
+ }
198625
+ return PSStackBasedInterpreter.build(program, domain, range3);
198626
+ }
196019
198627
  var PdfError2 = class extends Error {
196020
198628
  constructor(code, message) {
196021
198629
  super(message);
@@ -207095,6 +209703,25 @@ var __webpack_exports__JpxImage = __webpack_exports__.JpxImage;
207095
209703
  var __webpack_exports__VerbosityLevel = __webpack_exports__.VerbosityLevel;
207096
209704
  var __webpack_exports__getVerbosityLevel = __webpack_exports__.getVerbosityLevel;
207097
209705
  var __webpack_exports__setVerbosityLevel = __webpack_exports__.setVerbosityLevel;
209706
+ function createCalibratedColorSpace(doc, family, parameters) {
209707
+ const dict = doc.resolveDict(parameters);
209708
+ const array = (key) => {
209709
+ const value3 = dict ? doc.resolveArray(dictGet(dict, key)) : void 0;
209710
+ return value3?.items.map((item) => {
209711
+ const number5 = doc.resolve(item);
209712
+ return number5?.kind === "number" ? number5.value : 0;
209713
+ });
209714
+ };
209715
+ const whitePoint = array("WhitePoint") ?? [0.95047, 1, 1.08883];
209716
+ const blackPoint = array("BlackPoint");
209717
+ if (family === "CalGray") {
209718
+ const gamma2 = dict ? doc.resolve(dictGet(dict, "Gamma")) : void 0;
209719
+ return new CalGrayCS(whitePoint, blackPoint, gamma2?.kind === "number" ? gamma2.value : void 0);
209720
+ }
209721
+ if (family === "CalRGB") return new CalRGBCS(whitePoint, blackPoint, array("Gamma"), array("Matrix"));
209722
+ return new LabCS(whitePoint, blackPoint, array("Range"));
209723
+ }
209724
+ var cmykColorSpace = new DeviceCmykCS();
207098
209725
  function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
207099
209726
  if (!csNode) return { colorSpace: "rgb", colorSpaceLabel: "rgb", components: 3 };
207100
209727
  const resolved = doc.resolve(csNode);
@@ -207135,7 +209762,7 @@ function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
207135
209762
  palette2 = lookupNode.bytes;
207136
209763
  }
207137
209764
  let resolvedBaseComp = baseInfo.components;
207138
- if (palette2 && (baseInfo.isLab || baseInfo.isSeparation || baseInfo.isDeviceN || baseInfo.calRgbGamma !== void 0 || baseInfo.calGrayGamma !== void 0)) {
209765
+ if (palette2 && (baseInfo.isSeparation || baseInfo.isDeviceN || baseInfo.calibrated !== void 0)) {
207139
209766
  const numEntries = Math.max(1, Math.min(hival + 1, Math.floor(palette2.length / Math.max(1, baseInfo.components))));
207140
209767
  const rgbaPal = decodeSamplesToRgba(palette2, numEntries, 1, 8, baseInfo);
207141
209768
  const rgbPal = new Uint8Array(numEntries * 3);
@@ -207165,74 +209792,21 @@ function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
207165
209792
  }
207166
209793
  return { colorSpace: "rgb", colorSpaceLabel: "icc", components: 3 };
207167
209794
  }
207168
- if (kindName === "CalGray") {
207169
- const calDict = doc.resolveDict(resolved.items[1]);
207170
- const gammaNode = calDict ? doc.resolve(dictGet(calDict, "Gamma")) : void 0;
207171
- const gamma2 = gammaNode?.kind === "number" && gammaNode.value > 0 ? gammaNode.value : 1;
207172
- return { colorSpace: "gray", colorSpaceLabel: "cal-gray", components: 1, calGrayGamma: gamma2 };
207173
- }
207174
- if (kindName === "CalRGB") {
207175
- const calDict = doc.resolveDict(resolved.items[1]);
207176
- const gammaArr = calDict ? doc.resolveArray(dictGet(calDict, "Gamma")) : void 0;
207177
- let calRgbGamma = [1, 1, 1];
207178
- if (gammaArr && gammaArr.items.length >= 3) {
207179
- const gNums = gammaArr.items.slice(0, 3).map((it) => {
207180
- const r = doc.resolve(it);
207181
- return r?.kind === "number" && r.value > 0 ? r.value : 1;
207182
- });
207183
- calRgbGamma = [gNums[0], gNums[1], gNums[2]];
207184
- }
207185
- const matArr = calDict ? doc.resolveArray(dictGet(calDict, "Matrix")) : void 0;
207186
- let calRgbMatrix;
207187
- if (matArr && matArr.items.length >= 9) {
207188
- calRgbMatrix = matArr.items.slice(0, 9).map((it) => {
207189
- const r = doc.resolve(it);
207190
- return r?.kind === "number" ? r.value : 0;
207191
- });
207192
- }
209795
+ if (kindName === "CalGray" || kindName === "CalRGB" || kindName === "Lab") {
209796
+ const calibrated = createCalibratedColorSpace(doc, kindName, resolved.items[1]);
207193
209797
  return {
207194
- colorSpace: "rgb",
207195
- colorSpaceLabel: "cal-rgb",
207196
- components: 3,
207197
- calRgbGamma,
207198
- calRgbMatrix
209798
+ colorSpace: kindName === "CalGray" ? "gray" : "rgb",
209799
+ colorSpaceLabel: kindName === "CalGray" ? "cal-gray" : kindName === "CalRGB" ? "cal-rgb" : "lab",
209800
+ components: kindName === "CalGray" ? 1 : 3,
209801
+ calibrated
207199
209802
  };
207200
209803
  }
207201
- if (kindName === "Lab") {
207202
- const labDict = doc.resolveDict(resolved.items[1]);
207203
- const rangeArr = labDict ? doc.resolveArray(dictGet(labDict, "Range")) : void 0;
207204
- let labRange = [-100, 100, -100, 100];
207205
- if (rangeArr && rangeArr.items.length >= 4) {
207206
- const nums = rangeArr.items.slice(0, 4).map((it) => {
207207
- const r = doc.resolve(it);
207208
- return r?.kind === "number" ? r.value : 0;
207209
- });
207210
- labRange = [nums[0], nums[1], nums[2], nums[3]];
207211
- }
207212
- return { colorSpace: "rgb", colorSpaceLabel: "lab", components: 3, isLab: true, labRange };
207213
- }
207214
209804
  if (kindName === "Separation" || kindName === "DeviceN") {
207215
209805
  const isDevN = kindName === "DeviceN";
207216
209806
  const namesArr = isDevN ? doc.resolveArray(resolved.items[1]) : void 0;
207217
209807
  const devNComponents = isDevN && namesArr ? Math.max(1, namesArr.items.length) : 1;
207218
209808
  const altInfo = resolveColorSpaceInfo(doc, resolved.items[2], resourcesDict);
207219
209809
  const altSpace = altInfo.colorSpace === "cmyk" ? "cmyk" : altInfo.colorSpace === "gray" ? "gray" : "rgb";
207220
- const fnResolved = doc.resolve(resolved.items[3]);
207221
- const fnDict = fnResolved?.kind === "stream" ? fnResolved.dict : fnResolved?.kind === "dict" ? fnResolved : void 0;
207222
- const ftNode = fnDict ? doc.resolve(dictGet(fnDict, "FunctionType")) : void 0;
207223
- const tintFunctionType = ftNode?.kind === "number" ? ftNode.value : 2;
207224
- const c0Arr = fnDict ? doc.resolveArray(dictGet(fnDict, "C0")) : void 0;
207225
- const c1Arr = fnDict ? doc.resolveArray(dictGet(fnDict, "C1")) : void 0;
207226
- const nNode = fnDict ? doc.resolve(dictGet(fnDict, "N")) : void 0;
207227
- const c0 = c0Arr ? c0Arr.items.map((it) => {
207228
- const r = doc.resolve(it);
207229
- return r?.kind === "number" ? r.value : 0;
207230
- }) : altSpace === "cmyk" ? [0, 0, 0, 0] : altSpace === "gray" ? [1] : [1, 1, 1];
207231
- const c1 = c1Arr ? c1Arr.items.map((it) => {
207232
- const r = doc.resolve(it);
207233
- return r?.kind === "number" ? r.value : 0;
207234
- }) : altSpace === "cmyk" ? [0, 0, 0, 1] : altSpace === "gray" ? [0] : [0, 0, 0];
207235
- const sepN = nNode?.kind === "number" && nNode.value > 0 ? nNode.value : 1;
207236
209810
  return {
207237
209811
  colorSpace: altSpace,
207238
209812
  colorSpaceLabel: isDevN ? "devn" : "sep",
@@ -207240,12 +209814,9 @@ function resolveColorSpaceInfo(doc, csNode, resourcesDict) {
207240
209814
  isSeparation: !isDevN,
207241
209815
  isDeviceN: isDevN,
207242
209816
  separationAltSpace: altSpace,
207243
- separationC0: c0,
207244
- separationC1: c1,
207245
- separationN: sepN,
209817
+ alternateCalibrated: altInfo.calibrated,
207246
209818
  tintFunctionDoc: doc,
207247
- tintFunctionNode: resolved.items[3],
207248
- tintFunctionType
209819
+ tintFunctionNode: resolved.items[3]
207249
209820
  };
207250
209821
  }
207251
209822
  }
@@ -207395,141 +209966,55 @@ function decodeSamplesToRgba(rawSamples, width2, height, bpc, csInfo, alphaSampl
207395
209966
  const rgba = new Uint8Array(width2 * height * 4);
207396
209967
  const pixelCount = width2 * height;
207397
209968
  if (csInfo.isSeparation || csInfo.isDeviceN) {
207398
- const c0 = csInfo.separationC0 ?? [1, 1, 1];
207399
- const c1 = csInfo.separationC1 ?? [0, 0, 0];
207400
- const expN = csInfo.separationN ?? 1;
207401
209969
  const alt = csInfo.separationAltSpace ?? "rgb";
207402
209970
  const numCh = Math.max(1, csInfo.components);
207403
209971
  const step = bpc === 16 ? 2 : 1;
207404
- const useGenericTintFn = csInfo.tintFunctionDoc !== void 0 && csInfo.tintFunctionNode !== void 0 && (csInfo.tintFunctionType === 0 || csInfo.tintFunctionType === 3 || csInfo.tintFunctionType === 4);
207405
209972
  for (let p2 = 0; p2 < pixelCount; p2++) {
207406
209973
  const chVals = [];
207407
- let wSum = 0;
207408
209974
  for (let ch3 = 0; ch3 < numCh; ch3++) {
207409
209975
  const sRaw = (rawSamples[(p2 * numCh + ch3) * step] ?? 0) / 255;
207410
- const tRemapped = remapUnitSampleWithDecode(sRaw, ch3, decodePairs);
207411
- chVals.push(tRemapped);
207412
- wSum += Math.pow(Math.max(0, Math.min(1, tRemapped)), expN);
207413
- }
207414
- if (useGenericTintFn) {
207415
- const outComps = evalShadingFunctionToComponents(
207416
- csInfo.tintFunctionDoc,
207417
- csInfo.tintFunctionNode,
207418
- chVals
207419
- );
207420
- if (alt === "cmyk") {
207421
- const c4 = outComps[0] ?? 0;
207422
- const m = outComps[1] ?? 0;
207423
- const y = outComps[2] ?? 0;
207424
- const k = outComps[3] ?? 0;
207425
- rgba[p2 * 4] = Math.round(Math.max(0, Math.min(1, (1 - c4) * (1 - k))) * 255);
207426
- rgba[p2 * 4 + 1] = Math.round(Math.max(0, Math.min(1, (1 - m) * (1 - k))) * 255);
207427
- rgba[p2 * 4 + 2] = Math.round(Math.max(0, Math.min(1, (1 - y) * (1 - k))) * 255);
207428
- } else if (alt === "gray") {
207429
- const gByte = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
207430
- rgba[p2 * 4] = gByte;
207431
- rgba[p2 * 4 + 1] = gByte;
207432
- rgba[p2 * 4 + 2] = gByte;
207433
- } else {
207434
- rgba[p2 * 4] = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
207435
- rgba[p2 * 4 + 1] = Math.round(Math.max(0, Math.min(1, outComps[1] ?? 0)) * 255);
207436
- rgba[p2 * 4 + 2] = Math.round(Math.max(0, Math.min(1, outComps[2] ?? 0)) * 255);
207437
- }
207438
- rgba[p2 * 4 + 3] = 255;
207439
- continue;
209976
+ chVals.push(remapUnitSampleWithDecode(sRaw, ch3, decodePairs));
207440
209977
  }
207441
- const w = Math.max(0, Math.min(1, wSum));
207442
- if (alt === "cmyk") {
207443
- const c4 = (c0[0] ?? 0) + w * ((c1[0] ?? 0) - (c0[0] ?? 0));
207444
- const m = (c0[1] ?? 0) + w * ((c1[1] ?? 0) - (c0[1] ?? 0));
207445
- const y = (c0[2] ?? 0) + w * ((c1[2] ?? 0) - (c0[2] ?? 0));
207446
- const k = (c0[3] ?? 0) + w * ((c1[3] ?? 1) - (c0[3] ?? 0));
207447
- rgba[p2 * 4] = Math.round(Math.max(0, Math.min(1, (1 - c4) * (1 - k))) * 255);
207448
- rgba[p2 * 4 + 1] = Math.round(Math.max(0, Math.min(1, (1 - m) * (1 - k))) * 255);
207449
- rgba[p2 * 4 + 2] = Math.round(Math.max(0, Math.min(1, (1 - y) * (1 - k))) * 255);
209978
+ const outComps = evalShadingFunctionToComponents(
209979
+ csInfo.tintFunctionDoc,
209980
+ csInfo.tintFunctionNode,
209981
+ chVals
209982
+ );
209983
+ if (csInfo.alternateCalibrated) {
209984
+ rgba.set(csInfo.alternateCalibrated.getRgb(outComps, 0), p2 * 4);
209985
+ } else if (alt === "cmyk") {
209986
+ rgba.set(cmykColorSpace.getRgb([outComps[0] ?? 0, outComps[1] ?? 0, outComps[2] ?? 0, outComps[3] ?? 0], 0), p2 * 4);
207450
209987
  } else if (alt === "gray") {
207451
- const gVal = (c0[0] ?? 1) + w * ((c1[0] ?? 0) - (c0[0] ?? 1));
207452
- const gByte = Math.round(Math.max(0, Math.min(1, gVal)) * 255);
209988
+ const gByte = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
207453
209989
  rgba[p2 * 4] = gByte;
207454
209990
  rgba[p2 * 4 + 1] = gByte;
207455
209991
  rgba[p2 * 4 + 2] = gByte;
207456
209992
  } else {
207457
- const rVal = (c0[0] ?? 1) + w * ((c1[0] ?? 0) - (c0[0] ?? 1));
207458
- const gVal = (c0[1] ?? 1) + w * ((c1[1] ?? 0) - (c0[1] ?? 1));
207459
- const bVal = (c0[2] ?? 1) + w * ((c1[2] ?? 0) - (c0[2] ?? 1));
207460
- rgba[p2 * 4] = Math.round(Math.max(0, Math.min(1, rVal)) * 255);
207461
- rgba[p2 * 4 + 1] = Math.round(Math.max(0, Math.min(1, gVal)) * 255);
207462
- rgba[p2 * 4 + 2] = Math.round(Math.max(0, Math.min(1, bVal)) * 255);
209993
+ rgba[p2 * 4] = Math.round(Math.max(0, Math.min(1, outComps[0] ?? 0)) * 255);
209994
+ rgba[p2 * 4 + 1] = Math.round(Math.max(0, Math.min(1, outComps[1] ?? 0)) * 255);
209995
+ rgba[p2 * 4 + 2] = Math.round(Math.max(0, Math.min(1, outComps[2] ?? 0)) * 255);
207463
209996
  }
207464
209997
  rgba[p2 * 4 + 3] = 255;
207465
209998
  }
207466
- } else if (csInfo.isLab) {
207467
- const [amin, amax, bmin, bmax] = csInfo.labRange ?? [-100, 100, -100, 100];
207468
- const invF = (t) => t > 6 / 29 ? t * t * t : 3 * (6 / 29) * (6 / 29) * (t - 4 / 29);
207469
- const toSrgb = (u) => {
207470
- const c4 = u <= 31308e-7 ? 12.92 * u : 1.055 * Math.pow(u, 1 / 2.4) - 0.055;
207471
- return Math.round(Math.max(0, Math.min(1, c4)) * 255);
207472
- };
209999
+ } else if (csInfo.calibrated?.name === "Lab") {
210000
+ const { amin, amax, bmin, bmax } = csInfo.calibrated;
210001
+ const step = bpc === 16 ? 2 : 1;
207473
210002
  for (let p2 = 0; p2 < pixelCount; p2++) {
207474
- const s0 = (rawSamples[p2 * 3] ?? 0) / 255;
207475
- const s1 = (rawSamples[p2 * 3 + 1] ?? 128) / 255;
207476
- const s2 = (rawSamples[p2 * 3 + 2] ?? 128) / 255;
207477
- const L = s0 * 100;
207478
- if (L <= 0.01) {
207479
- rgba[p2 * 4] = 0;
207480
- rgba[p2 * 4 + 1] = 0;
207481
- rgba[p2 * 4 + 2] = 0;
207482
- rgba[p2 * 4 + 3] = 255;
207483
- continue;
207484
- }
207485
- const a3 = amin + s1 * (amax - amin);
207486
- const b3 = bmin + s2 * (bmax - bmin);
207487
- const fy = (L + 16) / 116;
207488
- const fx = fy + a3 / 500;
207489
- const fz = fy - b3 / 200;
207490
- const X = 0.95047 * invF(fx);
207491
- const Y = 1 * invF(fy);
207492
- const Z = 1.08883 * invF(fz);
207493
- const linR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
207494
- const linG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
207495
- const linB = X * 0.0557 + Y * -0.204 + Z * 1.057;
207496
- rgba[p2 * 4] = toSrgb(linR);
207497
- rgba[p2 * 4 + 1] = toSrgb(linG);
207498
- rgba[p2 * 4 + 2] = toSrgb(linB);
210003
+ const L = (rawSamples[p2 * 3 * step] ?? 0) / 255 * 100;
210004
+ const a3 = amin + (rawSamples[(p2 * 3 + 1) * step] ?? 128) / 255 * (amax - amin);
210005
+ const b3 = bmin + (rawSamples[(p2 * 3 + 2) * step] ?? 128) / 255 * (bmax - bmin);
210006
+ rgba.set(csInfo.calibrated.getRgb([L, a3, b3], 0), p2 * 4);
207499
210007
  rgba[p2 * 4 + 3] = 255;
207500
210008
  }
207501
210009
  } else if (csInfo.colorSpace === "rgb") {
207502
- const hasCalRgb = Boolean(csInfo.calRgbGamma || csInfo.calRgbMatrix);
207503
- const toSrgbByte = (u) => {
207504
- const c4 = u <= 31308e-7 ? 12.92 * u : 1.055 * Math.pow(u, 1 / 2.4) - 0.055;
207505
- return Math.round(Math.max(0, Math.min(1, c4)) * 255);
207506
- };
207507
210010
  const writeRgbPixel = (p2, rByte, gByte, bByte) => {
207508
- let rU = remapUnitSampleWithDecode(rByte / 255, 0, decodePairs);
207509
- let gU = remapUnitSampleWithDecode(gByte / 255, 1, decodePairs);
207510
- let bU = remapUnitSampleWithDecode(bByte / 255, 2, decodePairs);
207511
- if (hasCalRgb) {
207512
- const [gr, gg, gb] = csInfo.calRgbGamma ?? [1, 1, 1];
207513
- const ag = Math.pow(rU, gr);
207514
- const bg = Math.pow(gU, gg);
207515
- const cg = Math.pow(bU, gb);
207516
- if (csInfo.calRgbMatrix && csInfo.calRgbMatrix.length >= 9) {
207517
- const m = csInfo.calRgbMatrix;
207518
- const X = m[0] * ag + m[3] * bg + m[6] * cg;
207519
- const Y = m[1] * ag + m[4] * bg + m[7] * cg;
207520
- const Z = m[2] * ag + m[5] * bg + m[8] * cg;
207521
- const linR = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
207522
- const linG = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
207523
- const linB = X * 0.0557 + Y * -0.204 + Z * 1.057;
207524
- rgba[p2 * 4] = toSrgbByte(linR);
207525
- rgba[p2 * 4 + 1] = toSrgbByte(linG);
207526
- rgba[p2 * 4 + 2] = toSrgbByte(linB);
207527
- rgba[p2 * 4 + 3] = 255;
207528
- return;
207529
- }
207530
- rU = ag;
207531
- gU = bg;
207532
- bU = cg;
210011
+ const rU = remapUnitSampleWithDecode(rByte / 255, 0, decodePairs);
210012
+ const gU = remapUnitSampleWithDecode(gByte / 255, 1, decodePairs);
210013
+ const bU = remapUnitSampleWithDecode(bByte / 255, 2, decodePairs);
210014
+ if (csInfo.calibrated) {
210015
+ rgba.set(csInfo.calibrated.getRgb([rU, gU, bU], 0), p2 * 4);
210016
+ rgba[p2 * 4 + 3] = 255;
210017
+ return;
207533
210018
  }
207534
210019
  rgba[p2 * 4] = Math.round(rU * 255);
207535
210020
  rgba[p2 * 4 + 1] = Math.round(gU * 255);
@@ -207549,10 +210034,11 @@ function decodeSamplesToRgba(rawSamples, width2, height, bpc, csInfo, alphaSampl
207549
210034
  }
207550
210035
  } else if (csInfo.colorSpace === "gray") {
207551
210036
  const writeGrayPixel = (p2, gByte) => {
207552
- let gU = remapUnitSampleWithDecode(gByte / 255, 0, decodePairs);
207553
- if (csInfo.calGrayGamma && csInfo.calGrayGamma !== 1) {
207554
- const lin = Math.pow(gU, csInfo.calGrayGamma);
207555
- gU = lin <= 31308e-7 ? 12.92 * lin : 1.055 * Math.pow(lin, 1 / 2.4) - 0.055;
210037
+ const gU = remapUnitSampleWithDecode(gByte / 255, 0, decodePairs);
210038
+ if (csInfo.calibrated) {
210039
+ rgba.set(csInfo.calibrated.getRgb([gU], 0), p2 * 4);
210040
+ rgba[p2 * 4 + 3] = 255;
210041
+ return;
207556
210042
  }
207557
210043
  const outG = Math.round(Math.max(0, Math.min(1, gU)) * 255);
207558
210044
  rgba[p2 * 4] = outG;
@@ -207608,9 +210094,7 @@ function decodeSamplesToRgba(rawSamples, width2, height, bpc, csInfo, alphaSampl
207608
210094
  const m = remapUnitSampleWithDecode((rawSamples[p2 * stride + chStep] ?? 0) / 255, 1, decodePairs);
207609
210095
  const y = remapUnitSampleWithDecode((rawSamples[p2 * stride + chStep * 2] ?? 0) / 255, 2, decodePairs);
207610
210096
  const k = remapUnitSampleWithDecode((rawSamples[p2 * stride + chStep * 3] ?? 0) / 255, 3, decodePairs);
207611
- rgba[p2 * 4] = Math.round((1 - c4) * (1 - k) * 255);
207612
- rgba[p2 * 4 + 1] = Math.round((1 - m) * (1 - k) * 255);
207613
- rgba[p2 * 4 + 2] = Math.round((1 - y) * (1 - k) * 255);
210097
+ rgba.set(cmykColorSpace.getRgb([c4, m, y, k], 0), p2 * 4);
207614
210098
  rgba[p2 * 4 + 3] = 255;
207615
210099
  }
207616
210100
  } else if (csInfo.colorSpace === "index") {
@@ -207648,9 +210132,7 @@ function decodeSamplesToRgba(rawSamples, width2, height, bpc, csInfo, alphaSampl
207648
210132
  const m = pal[idx * 4 + 1] / 255;
207649
210133
  const yel = pal[idx * 4 + 2] / 255;
207650
210134
  const k = pal[idx * 4 + 3] / 255;
207651
- rgba[p2 * 4] = Math.round((1 - c4) * (1 - k) * 255);
207652
- rgba[p2 * 4 + 1] = Math.round((1 - m) * (1 - k) * 255);
207653
- rgba[p2 * 4 + 2] = Math.round((1 - yel) * (1 - k) * 255);
210135
+ rgba.set(cmykColorSpace.getRgb([c4, m, yel, k], 0), p2 * 4);
207654
210136
  } else {
207655
210137
  rgba[p2 * 4] = pal[idx * baseComp];
207656
210138
  rgba[p2 * 4 + 1] = pal[idx * baseComp + 1];
@@ -207905,6 +210387,7 @@ function decodeInlineImageNodeToRgba(doc, dict, rawData, activeRes, fillColor) {
207905
210387
  });
207906
210388
  return decodeXObjectImageToRgba(context, { kind: "stream", dict, rawBytes: rawData }, activeRes, fillColor);
207907
210389
  }
210390
+ var cmykColorSpace2 = new DeviceCmykCS();
207908
210391
  function multiplyMatrices(m1, m2) {
207909
210392
  return [
207910
210393
  m1[0] * m2[0] + m1[1] * m2[2],
@@ -208121,193 +210604,7 @@ function resolvePageFonts(doc, resourcesDict) {
208121
210604
  }
208122
210605
  return fonts;
208123
210606
  }
208124
- function evaluateType4PostScriptTokens(tokens3, initialStack) {
208125
- const stack = [...initialStack];
208126
- const runRange = (start, end2) => {
208127
- let i = start;
208128
- while (i < end2) {
208129
- const tok = tokens3[i];
208130
- if (tok === "{") {
208131
- let depth = 1;
208132
- let j = i + 1;
208133
- while (j < end2 && depth > 0) {
208134
- if (tokens3[j] === "{") depth++;
208135
- else if (tokens3[j] === "}") depth--;
208136
- j++;
208137
- }
208138
- const blockStart = i + 1;
208139
- const blockEnd = j - 1;
208140
- if (j < end2 && tokens3[j] === "{") {
208141
- let depth2 = 1;
208142
- let k = j + 1;
208143
- while (k < end2 && depth2 > 0) {
208144
- if (tokens3[k] === "{") depth2++;
208145
- else if (tokens3[k] === "}") depth2--;
208146
- k++;
208147
- }
208148
- if (k < end2 && tokens3[k] === "ifelse") {
208149
- const cond = stack.pop() ?? 0;
208150
- if (cond !== 0) runRange(blockStart, blockEnd);
208151
- else runRange(j + 1, k - 1);
208152
- i = k + 1;
208153
- continue;
208154
- }
208155
- }
208156
- if (j < end2 && tokens3[j] === "if") {
208157
- const cond = stack.pop() ?? 0;
208158
- if (cond !== 0) runRange(blockStart, blockEnd);
208159
- i = j + 1;
208160
- continue;
208161
- }
208162
- runRange(blockStart, blockEnd);
208163
- i = j;
208164
- continue;
208165
- }
208166
- if (tok === "}") {
208167
- i++;
208168
- continue;
208169
- }
208170
- const numVal2 = Number(tok);
208171
- if (tok.length > 0 && !Number.isNaN(numVal2)) {
208172
- stack.push(numVal2);
208173
- } else if (tok === "true") {
208174
- stack.push(1);
208175
- } else if (tok === "false") {
208176
- stack.push(0);
208177
- } else if (tok === "add") {
208178
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208179
- stack.push(a3 + b3);
208180
- } else if (tok === "sub") {
208181
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208182
- stack.push(a3 - b3);
208183
- } else if (tok === "mul") {
208184
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208185
- stack.push(a3 * b3);
208186
- } else if (tok === "div") {
208187
- const b3 = stack.pop() ?? 1, a3 = stack.pop() ?? 0;
208188
- stack.push(Math.abs(b3) > 1e-12 ? a3 / b3 : 0);
208189
- } else if (tok === "idiv") {
208190
- const b3 = stack.pop() ?? 1, a3 = stack.pop() ?? 0;
208191
- stack.push(Math.abs(b3) > 1e-12 ? Math.trunc(a3 / b3) : 0);
208192
- } else if (tok === "mod") {
208193
- const b3 = stack.pop() ?? 1, a3 = stack.pop() ?? 0;
208194
- stack.push(Math.abs(b3) > 1e-12 ? a3 % b3 : 0);
208195
- } else if (tok === "neg") {
208196
- stack.push(-(stack.pop() ?? 0));
208197
- } else if (tok === "abs") {
208198
- stack.push(Math.abs(stack.pop() ?? 0));
208199
- } else if (tok === "ceiling") {
208200
- stack.push(Math.ceil(stack.pop() ?? 0));
208201
- } else if (tok === "floor") {
208202
- stack.push(Math.floor(stack.pop() ?? 0));
208203
- } else if (tok === "round") {
208204
- stack.push(Math.round(stack.pop() ?? 0));
208205
- } else if (tok === "truncate" || tok === "cvi") {
208206
- stack.push(Math.trunc(stack.pop() ?? 0));
208207
- } else if (tok === "sqrt") {
208208
- stack.push(Math.sqrt(Math.max(0, stack.pop() ?? 0)));
208209
- } else if (tok === "sin") {
208210
- stack.push(Math.sin((stack.pop() ?? 0) * Math.PI / 180));
208211
- } else if (tok === "cos") {
208212
- stack.push(Math.cos((stack.pop() ?? 0) * Math.PI / 180));
208213
- } else if (tok === "atan") {
208214
- const dx = stack.pop() ?? 1, dy = stack.pop() ?? 0;
208215
- let deg = Math.atan2(dy, dx) * 180 / Math.PI;
208216
- if (deg < 0) deg += 360;
208217
- stack.push(deg);
208218
- } else if (tok === "exp") {
208219
- const exp = stack.pop() ?? 1, base = stack.pop() ?? 0;
208220
- stack.push(Math.pow(base, exp));
208221
- } else if (tok === "ln") {
208222
- stack.push(Math.log(Math.max(1e-12, stack.pop() ?? 1)));
208223
- } else if (tok === "log") {
208224
- stack.push(Math.log10(Math.max(1e-12, stack.pop() ?? 1)));
208225
- } else if (tok === "dup") {
208226
- if (stack.length > 0) stack.push(stack[stack.length - 1]);
208227
- } else if (tok === "exch") {
208228
- if (stack.length >= 2) {
208229
- const b3 = stack.pop(), a3 = stack.pop();
208230
- stack.push(b3, a3);
208231
- }
208232
- } else if (tok === "pop") {
208233
- stack.pop();
208234
- } else if (tok === "copy") {
208235
- const n = Math.max(0, Math.trunc(stack.pop() ?? 0));
208236
- const slice = stack.slice(Math.max(0, stack.length - n));
208237
- stack.push(...slice);
208238
- } else if (tok === "index") {
208239
- const n = Math.max(0, Math.trunc(stack.pop() ?? 0));
208240
- const idx = stack.length - 1 - n;
208241
- if (idx >= 0 && idx < stack.length) stack.push(stack[idx]);
208242
- } else if (tok === "roll") {
208243
- const jShift = Math.trunc(stack.pop() ?? 0);
208244
- const n = Math.max(0, Math.trunc(stack.pop() ?? 0));
208245
- if (n > 0 && stack.length >= n) {
208246
- const sub = stack.splice(stack.length - n, n);
208247
- const modShift = (jShift % n + n) % n;
208248
- const rolled = [...sub.slice(n - modShift), ...sub.slice(0, n - modShift)];
208249
- stack.push(...rolled);
208250
- }
208251
- } else if (tok === "eq") {
208252
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208253
- stack.push(Math.abs(a3 - b3) < 1e-9 ? 1 : 0);
208254
- } else if (tok === "ne") {
208255
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208256
- stack.push(Math.abs(a3 - b3) >= 1e-9 ? 1 : 0);
208257
- } else if (tok === "gt") {
208258
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208259
- stack.push(a3 > b3 ? 1 : 0);
208260
- } else if (tok === "ge") {
208261
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208262
- stack.push(a3 >= b3 ? 1 : 0);
208263
- } else if (tok === "lt") {
208264
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208265
- stack.push(a3 < b3 ? 1 : 0);
208266
- } else if (tok === "le") {
208267
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208268
- stack.push(a3 <= b3 ? 1 : 0);
208269
- } else if (tok === "and") {
208270
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208271
- stack.push(a3 !== 0 && b3 !== 0 ? 1 : 0);
208272
- } else if (tok === "or") {
208273
- const b3 = stack.pop() ?? 0, a3 = stack.pop() ?? 0;
208274
- stack.push(a3 !== 0 || b3 !== 0 ? 1 : 0);
208275
- } else if (tok === "not") {
208276
- const a3 = stack.pop() ?? 0;
208277
- stack.push(a3 === 0 ? 1 : 0);
208278
- }
208279
- i++;
208280
- }
208281
- };
208282
- runRange(0, tokens3.length);
208283
- return stack;
208284
- }
208285
- function tokenizePostScriptCode(bytes) {
208286
- const tokens3 = [];
208287
- let cur = "";
208288
- for (let i = 0; i < bytes.length; i++) {
208289
- const ch3 = String.fromCharCode(bytes[i]);
208290
- if (ch3 === "{" || ch3 === "}") {
208291
- if (cur.length > 0) {
208292
- tokens3.push(cur);
208293
- cur = "";
208294
- }
208295
- tokens3.push(ch3);
208296
- } else if (ch3 === " " || ch3 === " " || ch3 === "\n" || ch3 === "\r") {
208297
- if (cur.length > 0) {
208298
- tokens3.push(cur);
208299
- cur = "";
208300
- }
208301
- } else {
208302
- cur += ch3;
208303
- }
208304
- }
208305
- if (cur.length > 0) tokens3.push(cur);
208306
- if (tokens3[0] === "{" && tokens3[tokens3.length - 1] === "}") {
208307
- return tokens3.slice(1, -1);
208308
- }
208309
- return tokens3;
208310
- }
210607
+ var postScriptFunctions = /* @__PURE__ */ new WeakMap();
208311
210608
  function evalShadingFunctionToComponents(doc, fnNode, inputs) {
208312
210609
  const inArr = typeof inputs === "number" ? [inputs] : inputs;
208313
210610
  const t = inArr[0] ?? 0;
@@ -208354,35 +210651,50 @@ function evalShadingFunctionToComponents(doc, fnNode, inputs) {
208354
210651
  const decode3 = getNums("Decode", range3);
208355
210652
  const nOut = Math.max(1, Math.floor((decode3.length || range3.length || 6) / 2));
208356
210653
  const mIn = Math.max(1, size.length);
208357
- let flatGridIndex = 0;
210654
+ const streamBytes = doc.decodeStream(resolved);
210655
+ let vertices = [{ index: 0, weight: 1 }];
208358
210656
  let stride = 1;
208359
210657
  for (let i = 0; i < mIn; i++) {
208360
210658
  const d02 = dom[i * 2] ?? 0;
208361
210659
  const d12 = dom[i * 2 + 1] ?? 1;
208362
- const sMax = Math.max(1, (size[i] ?? 2) - 1);
210660
+ const sMax = Math.max(0, (size[i] ?? 2) - 1);
208363
210661
  const e0 = encode[i * 2] ?? 0;
208364
210662
  const e1 = encode[i * 2 + 1] ?? sMax;
208365
210663
  const x = Math.max(d02, Math.min(d12, inArr[i] ?? 0));
208366
- const u = Math.abs(d12 - d02) > 1e-8 ? (x - d02) / (d12 - d02) : 0;
208367
- const idx = Math.round(Math.max(0, Math.min(sMax, e0 + u * (e1 - e0))));
208368
- flatGridIndex += idx * stride;
210664
+ const u = d12 === d02 ? 0 : (x - d02) / (d12 - d02);
210665
+ const e = Math.max(0, Math.min(sMax, e0 + u * (e1 - e0)));
210666
+ const low = Math.floor(e), fraction = e - low;
210667
+ const next = [];
210668
+ for (const vertex of vertices) {
210669
+ const index2 = vertex.index + low * stride;
210670
+ if (index2 * nOut * bps < streamBytes.length * 8) next.push({ index: index2, weight: vertex.weight * (1 - fraction) });
210671
+ if (fraction && (index2 + stride) * nOut * bps < streamBytes.length * 8) {
210672
+ next.push({ index: index2 + stride, weight: vertex.weight * fraction });
210673
+ }
210674
+ }
210675
+ vertices = next;
208369
210676
  stride *= size[i] ?? 2;
208370
210677
  }
208371
- const streamBytes = doc.decodeStream(resolved);
210678
+ const maxSample = 2 ** bps - 1;
210679
+ const readSample = (index2) => {
210680
+ let bitOffset = index2 * bps, remaining = bps, value3 = 0;
210681
+ while (remaining > 0) {
210682
+ const bitInByte = bitOffset % 8;
210683
+ const take = Math.min(remaining, 8 - bitInByte);
210684
+ const byte = streamBytes[Math.floor(bitOffset / 8)] ?? 0;
210685
+ value3 = value3 * 2 ** take + (byte >> 8 - bitInByte - take & (1 << take) - 1);
210686
+ bitOffset += take;
210687
+ remaining -= take;
210688
+ }
210689
+ return value3 / maxSample;
210690
+ };
208372
210691
  const out2 = [];
208373
- const maxSample = bps === 16 ? 65535 : 255;
208374
210692
  for (let j = 0; j < nOut; j++) {
208375
- const sampleIdx = flatGridIndex * nOut + j;
208376
- let rawVal = 0;
208377
- if (bps === 16) {
208378
- rawVal = (streamBytes[sampleIdx * 2] ?? 0) << 8 | (streamBytes[sampleIdx * 2 + 1] ?? 0);
208379
- } else {
208380
- rawVal = streamBytes[sampleIdx] ?? 0;
208381
- }
208382
- const frac = rawVal / maxSample;
210693
+ let value3 = 0;
210694
+ for (const vertex of vertices) value3 += readSample(vertex.index * nOut + j) * vertex.weight;
208383
210695
  const dec0 = decode3[j * 2] ?? 0;
208384
210696
  const dec1 = decode3[j * 2 + 1] ?? 1;
208385
- out2.push(dec0 + frac * (dec1 - dec0));
210697
+ out2.push(dec0 + value3 * (dec1 - dec0));
208386
210698
  }
208387
210699
  return clampRange(out2);
208388
210700
  }
@@ -208392,34 +210704,40 @@ function evalShadingFunctionToComponents(doc, fnNode, inputs) {
208392
210704
  const d12 = dom[i * 2 + 1] ?? 1;
208393
210705
  return Math.max(d02, Math.min(d12, v));
208394
210706
  });
208395
- const tokens3 = tokenizePostScriptCode(doc.decodeStream(resolved));
208396
- const stackOut = evaluateType4PostScriptTokens(tokens3, clampedInputs);
208397
- return clampRange(stackOut);
210707
+ const source = bytesToString3(doc.decodeStream(resolved));
210708
+ let cached = postScriptFunctions.get(resolved);
210709
+ if (!cached || cached.source !== source || cached.domain.length !== dom.length || cached.domain.some((value3, index2) => value3 !== dom[index2]) || cached.range.length !== range3.length || cached.range.some((value3, index2) => value3 !== range3[index2])) {
210710
+ cached = { source, domain: dom, range: range3, evaluate: buildPostScriptJsFunction(source, dom, range3) };
210711
+ postScriptFunctions.set(resolved, cached);
210712
+ }
210713
+ const output2 = [];
210714
+ cached.evaluate(clampedInputs, 0, output2, 0);
210715
+ return output2;
208398
210716
  }
208399
210717
  if (ft === 3) {
208400
210718
  const fnsArr = doc.resolveArray(dictGet(fnDict, "Functions"));
208401
210719
  const bounds2 = getNums("Bounds", []);
208402
210720
  const encode = getNums("Encode", []);
208403
210721
  if (fnsArr && fnsArr.items.length > 0) {
210722
+ const input = Math.max(dom[0] ?? 0, Math.min(dom[1] ?? 1, t));
208404
210723
  let segIdx = 0;
208405
- while (segIdx < bounds2.length && t >= bounds2[segIdx]) segIdx++;
210724
+ while (segIdx < bounds2.length && input >= bounds2[segIdx]) segIdx++;
208406
210725
  segIdx = Math.min(fnsArr.items.length - 1, segIdx);
208407
210726
  const b0 = segIdx === 0 ? dom[0] ?? 0 : bounds2[segIdx - 1];
208408
210727
  const b1 = segIdx < bounds2.length ? bounds2[segIdx] : dom[1] ?? 1;
208409
210728
  const e0 = encode[segIdx * 2] ?? 0;
208410
210729
  const e1 = encode[segIdx * 2 + 1] ?? 1;
208411
- const localT = Math.abs(b1 - b0) > 1e-8 ? e0 + (t - b0) / (b1 - b0) * (e1 - e0) : e0;
208412
- return evalShadingFunctionToComponents(doc, fnsArr.items[segIdx], Math.max(0, Math.min(1, localT)));
210730
+ const localT = b1 !== b0 ? e0 + (input - b0) / (b1 - b0) * (e1 - e0) : e0;
210731
+ return clampRange(evalShadingFunctionToComponents(doc, fnsArr.items[segIdx], localT));
208413
210732
  }
208414
210733
  }
208415
- const c0 = getNums("C0", [0, 0, 0]);
208416
- const c1 = getNums("C1", [1, 1, 1]);
210734
+ const c0 = getNums("C0", [0]);
210735
+ const c1 = getNums("C1", [1]);
208417
210736
  const nNode = doc.resolve(dictGet(fnDict, "N"));
208418
- const expN = nNode?.kind === "number" && nNode.value > 0 ? nNode.value : 1;
210737
+ const expN = nNode?.kind === "number" ? nNode.value : 1;
208419
210738
  const d0 = dom[0] ?? 0;
208420
210739
  const d1 = dom[1] ?? 1;
208421
- const normT = Math.abs(d1 - d0) > 1e-8 ? (t - d0) / (d1 - d0) : t;
208422
- const w = Math.pow(Math.max(0, Math.min(1, normT)), expN);
210740
+ const w = Math.pow(Math.max(d0, Math.min(d1, t)), expN);
208423
210741
  const len = Math.max(c0.length, c1.length);
208424
210742
  const out = [];
208425
210743
  for (let i = 0; i < len; i++) {
@@ -208435,30 +210753,14 @@ function shadingComponentsToRgb(csName, comps) {
208435
210753
  return [v, v, v];
208436
210754
  }
208437
210755
  if (csName === "DeviceCMYK" || csName === "CMYK" || comps.length >= 4) {
208438
- const cc = comps[0] ?? 0, cm = comps[1] ?? 0, cy = comps[2] ?? 0, ck = comps[3] ?? 0;
208439
- return [(1 - cc) * (1 - ck), (1 - cm) * (1 - kClamp(ck)), (1 - cy) * (1 - kClamp(ck))];
210756
+ const rgb22 = cmykColorSpace2.getRgb([comps[0] ?? 0, comps[1] ?? 0, comps[2] ?? 0, comps[3] ?? 0], 0);
210757
+ return [rgb22[0] / 255, rgb22[1] / 255, rgb22[2] / 255];
208440
210758
  }
208441
210759
  return [comps[0] ?? 0, comps[1] ?? 0, comps[2] ?? 0];
208442
210760
  }
208443
210761
  function kClamp(v) {
208444
210762
  return Math.max(0, Math.min(1, v));
208445
210763
  }
208446
- function xyzToSrgb(X, Y, Z, Xw = 0.95047, Yw = 1, Zw = 1.08883) {
208447
- const scaleX = Xw > 1e-6 ? 0.95047 / Xw : 1;
208448
- const scaleY = Yw > 1e-6 ? 1 / Yw : 1;
208449
- const scaleZ = Zw > 1e-6 ? 1.08883 / Zw : 1;
208450
- const x = X * scaleX;
208451
- const y = Y * scaleY;
208452
- const z = Z * scaleZ;
208453
- const rl = 3.2404542 * x - 1.5371385 * y - 0.4985314 * z;
208454
- const gl = -0.969266 * x + 1.8760108 * y + 0.041556 * z;
208455
- const bl = 0.0556434 * x - 0.2040259 * y + 1.0572252 * z;
208456
- const toGamma = (u) => {
208457
- const c4 = Math.max(0, Math.min(1, u));
208458
- return c4 <= 31308e-7 ? 12.92 * c4 : 1.055 * Math.pow(c4, 1 / 2.4) - 0.055;
208459
- };
208460
- return [toGamma(rl), toGamma(gl), toGamma(bl)];
208461
- }
208462
210764
  function getColorSpaceComponentCount(doc, csNode, activeResources, depth = 0) {
208463
210765
  if (!csNode || depth > 4) return 3;
208464
210766
  const resolved = doc ? doc.resolve(csNode) : csNode;
@@ -208515,63 +210817,10 @@ function convertColorSpaceComponentsToRgb(doc, csNode, csNameFallback, comps, ac
208515
210817
  if (resolved.kind === "array" && resolved.items.length > 0 && doc) {
208516
210818
  const familyNode = doc.resolve(resolved.items[0]);
208517
210819
  const family = familyNode?.kind === "name" ? familyNode.decoded : "";
208518
- if (family === "CalGray") {
208519
- const paramDict = resolved.items[1] ? doc.resolveDict(resolved.items[1]) : void 0;
208520
- const gNode = paramDict ? doc.resolve(dictGet(paramDict, "Gamma")) : void 0;
208521
- const gamma2 = gNode?.kind === "number" && gNode.value > 0 ? gNode.value : 1;
208522
- const a3 = Math.pow(kClamp(comps[0] ?? 0), gamma2);
208523
- return [a3, a3, a3];
208524
- }
208525
- if (family === "CalRGB") {
208526
- const paramDict = resolved.items[1] ? doc.resolveDict(resolved.items[1]) : void 0;
208527
- const gammaArr = paramDict ? doc.resolveArray(dictGet(paramDict, "Gamma")) : void 0;
208528
- const getArrNum = (arr, idx, fb) => {
208529
- const r = arr && arr.items[idx] ? doc.resolve(arr.items[idx]) : void 0;
208530
- return r?.kind === "number" ? r.value : fb;
208531
- };
208532
- const gr = getArrNum(gammaArr, 0, 1);
208533
- const gg = getArrNum(gammaArr, 1, 1);
208534
- const gb = getArrNum(gammaArr, 2, 1);
208535
- const ag = Math.pow(kClamp(comps[0] ?? 0), gr > 0 ? gr : 1);
208536
- const bg = Math.pow(kClamp(comps[1] ?? 0), gg > 0 ? gg : 1);
208537
- const cg = Math.pow(kClamp(comps[2] ?? 0), gb > 0 ? gb : 1);
208538
- const matArr = paramDict ? doc.resolveArray(dictGet(paramDict, "Matrix")) : void 0;
208539
- if (matArr && matArr.items.length >= 9) {
208540
- const m = (i) => getArrNum(matArr, i, 0);
208541
- const X = m(0) * ag + m(3) * bg + m(6) * cg;
208542
- const Y = m(1) * ag + m(4) * bg + m(7) * cg;
208543
- const Z = m(2) * ag + m(5) * bg + m(8) * cg;
208544
- const wpArr = paramDict ? doc.resolveArray(dictGet(paramDict, "WhitePoint")) : void 0;
208545
- const Xw = getArrNum(wpArr, 0, 0.95047);
208546
- const Yw = getArrNum(wpArr, 1, 1);
208547
- const Zw = getArrNum(wpArr, 2, 1.08883);
208548
- return xyzToSrgb(X, Y, Z, Xw, Yw, Zw);
208549
- }
208550
- return [ag, bg, cg];
208551
- }
208552
- if (family === "Lab") {
208553
- const paramDict = resolved.items[1] ? doc.resolveDict(resolved.items[1]) : void 0;
208554
- const wpArr = paramDict ? doc.resolveArray(dictGet(paramDict, "WhitePoint")) : void 0;
208555
- const rangeArr = paramDict ? doc.resolveArray(dictGet(paramDict, "Range")) : void 0;
208556
- const getNum = (arr, idx, fb) => {
208557
- const r = arr && arr.items[idx] ? doc.resolve(arr.items[idx]) : void 0;
208558
- return r?.kind === "number" ? r.value : fb;
208559
- };
208560
- const Xw = getNum(wpArr, 0, 0.95047);
208561
- const Yw = getNum(wpArr, 1, 1);
208562
- const Zw = getNum(wpArr, 2, 1.08883);
208563
- const amin = getNum(rangeArr, 0, -100);
208564
- const amax = getNum(rangeArr, 1, 100);
208565
- const bmin = getNum(rangeArr, 2, -100);
208566
- const bmax = getNum(rangeArr, 3, 100);
208567
- const Lstar = Math.max(0, Math.min(100, comps[0] ?? 0));
208568
- const astar = Math.max(amin, Math.min(amax, comps[1] ?? 0));
208569
- const bstar = Math.max(bmin, Math.min(bmax, comps[2] ?? 0));
208570
- const M = (Lstar + 16) / 116;
208571
- const L = M + astar / 500;
208572
- const N = M - bstar / 200;
208573
- const gFn = (x) => x >= 6 / 29 ? x * x * x : 108 / 841 * (x - 4 / 29);
208574
- return xyzToSrgb(Xw * gFn(L), Yw * gFn(M), Zw * gFn(N), Xw, Yw, Zw);
210820
+ if (family === "CalGray" || family === "CalRGB" || family === "Lab") {
210821
+ const colorSpace = createCalibratedColorSpace(doc, family, resolved.items[1]);
210822
+ const rgb22 = colorSpace.getRgb(comps, 0);
210823
+ return [rgb22[0] / 255, rgb22[1] / 255, rgb22[2] / 255];
208575
210824
  }
208576
210825
  if (family === "ICCBased" && resolved.items[1]) {
208577
210826
  const iccNode = doc.resolve(resolved.items[1]);
@@ -209222,7 +211471,8 @@ function evaluateContentStreamToDisplayList(params) {
209222
211471
  const shDict = shNode?.kind === "dict" ? shNode : shNode?.kind === "stream" ? shNode.dict : void 0;
209223
211472
  const shStream = shNode?.kind === "stream" ? shNode : void 0;
209224
211473
  if (shDict) {
209225
- const targetBox = st.clipRect ?? [0, 0, params.width, params.height];
211474
+ const [originX, originY] = params.origin ?? [0, 0];
211475
+ const targetBox = st.clipRect ?? [originX, originY, originX + params.width, originY + params.height];
209226
211476
  const img = renderShadingDictToImage(
209227
211477
  params.cosDoc,
209228
211478
  shDict,
@@ -209261,12 +211511,10 @@ function evaluateContentStreamToDisplayList(params) {
209261
211511
  } else if (operator === "RG" || operator === "SC" || operator === "SCN") {
209262
211512
  st.strokeColor = resolveScColorOperands(operator === "RG" ? "DeviceRGB" : st.strokeColorSpaceName, ops, activeResources);
209263
211513
  } else if (operator === "k") {
209264
- const c4 = num(0), m = num(1), y = num(2), k = num(3);
209265
- st.fillColor = { r: (1 - c4) * (1 - k), g: (1 - m) * (1 - k), b: (1 - y) * (1 - k) };
211514
+ st.fillColor = resolveScColorOperands("DeviceCMYK", ops, activeResources);
209266
211515
  st.fillPatternName = void 0;
209267
211516
  } else if (operator === "K") {
209268
- const c4 = num(0), m = num(1), y = num(2), k = num(3);
209269
- st.strokeColor = { r: (1 - c4) * (1 - k), g: (1 - m) * (1 - k), b: (1 - y) * (1 - k) };
211517
+ st.strokeColor = resolveScColorOperands("DeviceCMYK", ops, activeResources);
209270
211518
  } else if (operator === "gs" && params.cosDoc && activeResources && ops[0]?.kind === "name") {
209271
211519
  const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
209272
211520
  const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
@@ -209475,7 +211723,7 @@ function evaluateContentStreamToDisplayList(params) {
209475
211723
  stateStack.pop();
209476
211724
  capturedOperations = parentOperations;
209477
211725
  }
209478
- if (compositeGroup) emit({ kind: "group", value: { operations: children8, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
211726
+ if (compositeGroup) emit({ kind: "group", value: { operations: children8, alpha: st.fillAlpha, isolated, bboxClip: nextClipPaths?.[0], blendMode: st.blendMode, clipRect: st.clipRect } });
209479
211727
  };
209480
211728
  const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
209481
211729
  for (const node3 of nodes) {
@@ -210059,6 +212307,7 @@ function evaluateContentStreamToDisplayList(params) {
210059
212307
  pageIndex: params.pageIndex,
210060
212308
  width: params.width,
210061
212309
  height: params.height,
212310
+ ...params.origin ? { origin: params.origin } : {},
210062
212311
  rotation: params.rotation ?? 0,
210063
212312
  glyphs,
210064
212313
  paths,
@@ -211529,7 +213778,7 @@ var PdfPage = class {
211529
213778
  return [n0.value, n1.value, n2.value, n3.value];
211530
213779
  }
211531
213780
  }
211532
- return [0, 0, 612, 792];
213781
+ return key === "MediaBox" ? [0, 0, 612, 792] : this.resolveBox("MediaBox");
211533
213782
  }
211534
213783
  getMediaBox() {
211535
213784
  return this.resolveBox("MediaBox");
@@ -212202,16 +214451,19 @@ var PdfPage = class {
212202
214451
  });
212203
214452
  }
212204
214453
  }
212205
- return evaluateContentStreamToDisplayList({
214454
+ const mediaBox = this.getMediaBox(), cropBox = this.getCropBox();
214455
+ const originX = Math.min(mediaBox[0], mediaBox[2]), originY = Math.min(mediaBox[1], mediaBox[3]);
214456
+ return { ...evaluateContentStreamToDisplayList({
212206
214457
  pageIndex: this.index,
212207
214458
  width: width2,
212208
214459
  height,
214460
+ origin: [originX, originY],
212209
214461
  rotation: this.getRotation(),
212210
214462
  nodes: baseNodes,
212211
214463
  cosDoc: this.cosDoc,
212212
214464
  resourcesDict: evalResourcesDict,
212213
214465
  annotations: extractPageAnnotations(this.cosDoc, this.pageDict)
212214
- });
214466
+ }), cropBox: [cropBox[0] - originX, cropBox[1] - originY, cropBox[2] - originX, cropBox[3] - originY] };
212215
214467
  }
212216
214468
  extractPage(options) {
212217
214469
  const dl = this.evaluateDisplayList();
@@ -212229,10 +214481,10 @@ var PdfPage = class {
212229
214481
  return extractTablesFromDisplayList(this.evaluateDisplayList());
212230
214482
  }
212231
214483
  renderToBitmap(options) {
212232
- return renderDisplayListToBitmap(this.evaluateDisplayList(), options);
214484
+ return renderDisplayListToBitmap(this.evaluateDisplayList({ hideAnnotations: options?.hideAnnotations }), options);
212233
214485
  }
212234
214486
  renderToPng(options) {
212235
- return renderDisplayListToPng(this.evaluateDisplayList(), options);
214487
+ return renderDisplayListToPng(this.evaluateDisplayList({ hideAnnotations: options?.hideAnnotations }), options);
212236
214488
  }
212237
214489
  };
212238
214490
  function createStandardFontHandle(standardName) {
@@ -213282,7 +215534,7 @@ function prepareStroke(path2, scale2) {
213282
215534
  }
213283
215535
  return { matrix: matrix2, width: width2, dashArray, dashPhase };
213284
215536
  }
213285
- function strokeContours(path2, pageHeight, scale2) {
215537
+ function strokeContours(path2, pageHeight, scale2, originX = 0, originY = 0) {
213286
215538
  const stroke = prepareStroke(path2, scale2);
213287
215539
  if (!stroke) return [];
213288
215540
  const inverse2 = inverseStrokeMatrix(stroke.matrix);
@@ -213294,8 +215546,8 @@ function strokeContours(path2, pageHeight, scale2) {
213294
215546
  (inverse2[1] * x + inverse2[3] * y + inverse2[5]) * strokeScale
213295
215547
  ];
213296
215548
  const toScreen = ([x, y]) => [
213297
- (a3 * x / strokeScale + c4 * y / strokeScale + e) * scale2,
213298
- (pageHeight - b3 * x / strokeScale - d2 * y / strokeScale - f2) * scale2
215549
+ (a3 * x / strokeScale + c4 * y / strokeScale + e - originX) * scale2,
215550
+ (pageHeight + originY - b3 * x / strokeScale - d2 * y / strokeScale - f2) * scale2
213299
215551
  ];
213300
215552
  const contours = strokeOutlines(
213301
215553
  segmentsToScreenPaths(path2.segments, pageHeight, scale2, project),
@@ -213453,18 +215705,34 @@ function renderSoftMask(mask, displayList, scale2) {
213453
215705
  }
213454
215706
  return bitmap;
213455
215707
  }
213456
- function hasBlendModes(operations) {
213457
- return operations.some((operation) => !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasBlendModes(operation.value.operations));
215708
+ function getDisplayListCropBox(list) {
215709
+ const full = [0, 0, list.width, list.height];
215710
+ const box = list.cropBox;
215711
+ if (!box || !box.every(Number.isFinite)) return full;
215712
+ const x0 = Math.max(0, Math.min(box[0], box[2]));
215713
+ const y0 = Math.max(0, Math.min(box[1], box[3]));
215714
+ const x1 = Math.min(list.width, Math.max(box[0], box[2]));
215715
+ const y1 = Math.min(list.height, Math.max(box[1], box[3]));
215716
+ return x1 > x0 && y1 > y0 ? [x0, y0, x1, y1] : full;
215717
+ }
215718
+ function hasCompositingEffects(operations, includeSoftMasks = false) {
215719
+ 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));
215720
+ }
215721
+ function needsGroupBackdrop(group) {
215722
+ return group.isolated === false && !!group.softMask && hasCompositingEffects(group.operations, true);
213458
215723
  }
213459
215724
  function renderDisplayListToBitmap(displayList, options = {}) {
213460
215725
  const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
213461
215726
  const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
213462
215727
  const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
213463
215728
  const scale2 = scaleX;
215729
+ const [originX, originY] = displayList.origin ?? [0, 0];
215730
+ const pageTop = originY + displayList.height;
215731
+ const toScreen = (x, y) => [(x - originX) * scale2, (pageTop - y) * scale2];
213464
215732
  const width2 = Math.max(1, Math.round(displayList.width * scale2));
213465
215733
  const height = Math.max(1, Math.round(displayList.height * scale2));
213466
215734
  const rgba = new Uint8Array(width2 * height * 4);
213467
- const deferBackground = !options.transparent && hasBlendModes(paintOperations(displayList));
215735
+ const deferBackground = !options.transparent && hasCompositingEffects(paintOperations(displayList));
213468
215736
  const transparent = options.transparent || deferBackground;
213469
215737
  const bg = options.background ?? { r: 1, g: 1, b: 1 };
213470
215738
  const bgR = transparent ? 0 : Math.round(bg.r * 255);
@@ -213489,14 +215757,27 @@ function renderDisplayListToBitmap(displayList, options = {}) {
213489
215757
  let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
213490
215758
  if (operation.kind === "group") {
213491
215759
  const group = operation.value;
213492
- const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale: scale2, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
215760
+ let operations = group.operations;
215761
+ if (needsGroupBackdrop(group)) {
215762
+ operations = [{ kind: "image", value: {
215763
+ name: "GroupBackdrop",
215764
+ width: width2,
215765
+ height,
215766
+ decodedRgba: rgba.slice(),
215767
+ matrix: [width2 / scale2, 0, 0, height / scale2, originX, pageTop - height / scale2],
215768
+ colorSpace: "DeviceRGB",
215769
+ bitsPerComponent: 8,
215770
+ ...group.bboxClip ? { clipPaths: [group.bboxClip] } : {}
215771
+ } }, ...operations];
215772
+ }
215773
+ const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations }, { ...options, scale: scale2, dpiX: void 0, dpiY: void 0, cropRect: void 0, useCropBox: false, transparent: true });
213493
215774
  for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
213494
215775
  operation = { kind: "image", value: {
213495
215776
  name: "TransparencyGroup",
213496
215777
  width: bitmap.width,
213497
215778
  height: bitmap.height,
213498
215779
  decodedRgba: bitmap.data,
213499
- matrix: [bitmap.width / scale2, 0, 0, bitmap.height / scale2, 0, displayList.height - bitmap.height / scale2],
215780
+ matrix: [bitmap.width / scale2, 0, 0, bitmap.height / scale2, originX, pageTop - bitmap.height / scale2],
213500
215781
  colorSpace: "DeviceRGB",
213501
215782
  bitsPerComponent: 8,
213502
215783
  blendMode: group.blendMode,
@@ -213510,7 +215791,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
213510
215791
  for (const clip2 of clips) {
213511
215792
  const { segments, fillRule } = "segments" in clip2 ? clip2 : { segments: clip2, fillRule: "nonzero" };
213512
215793
  const layer = new Uint8Array(width2 * height * 4);
213513
- fillEdgesScanline4x4(layer, width2, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale2), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
215794
+ fillEdgesScanline4x4(layer, width2, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale2, toScreen), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
213514
215795
  for (let i = 3; i < layer.length; i += 4) clipMask[i] = Math.round(clipMask[i] * layer[i] / 255);
213515
215796
  }
213516
215797
  cachedClips = clips;
@@ -213557,15 +215838,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
213557
215838
  if (operation.kind === "path") {
213558
215839
  const path2 = operation.value;
213559
215840
  if (path2.fillColor) {
213560
- const edges2 = pathsToEdges(segmentsToScreenPaths(path2.segments, displayList.height, scale2), true);
213561
- const clipScreen = path2.clipRect ? [path2.clipRect[0] * scale2, (displayList.height - path2.clipRect[3]) * scale2, path2.clipRect[2] * scale2, (displayList.height - path2.clipRect[1]) * scale2] : void 0;
215841
+ const edges2 = pathsToEdges(segmentsToScreenPaths(path2.segments, displayList.height, scale2, toScreen), true);
215842
+ const clipScreen = path2.clipRect ? [(path2.clipRect[0] - originX) * scale2, (pageTop - path2.clipRect[3]) * scale2, (path2.clipRect[2] - originX) * scale2, (pageTop - path2.clipRect[1]) * scale2] : void 0;
213562
215843
  fillEdgesScanline4x4(rgba, width2, height, edges2, path2.fillColor, path2.fillAlpha ?? 1, path2.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path2.blendMode, clipMask);
213563
215844
  }
213564
215845
  if (path2.strokeColor) {
213565
215846
  const rawSw = path2.strokeWidth * scale2 * (path2.strokeMatrix ? Math.hypot(path2.strokeMatrix[0], path2.strokeMatrix[1]) : 1);
213566
215847
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path2.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path2.strokeAlpha ?? 1;
213567
- const edges2 = pathsToEdges(strokeContours(path2, displayList.height, scale2).map((points) => ({ points, closed: true })));
213568
- const clipScreen = path2.clipRect ? [path2.clipRect[0] * scale2, (displayList.height - path2.clipRect[3]) * scale2, path2.clipRect[2] * scale2, (displayList.height - path2.clipRect[1]) * scale2] : void 0;
215848
+ const edges2 = pathsToEdges(strokeContours(path2, displayList.height, scale2, originX, originY).map((points) => ({ points, closed: true })));
215849
+ const clipScreen = path2.clipRect ? [(path2.clipRect[0] - originX) * scale2, (pageTop - path2.clipRect[3]) * scale2, (path2.clipRect[2] - originX) * scale2, (pageTop - path2.clipRect[1]) * scale2] : void 0;
213569
215850
  fillEdgesScanline4x4(
213570
215851
  rgba,
213571
215852
  width2,
@@ -213588,12 +215869,12 @@ function renderDisplayListToBitmap(displayList, options = {}) {
213588
215869
  if (Math.abs(det) <= 1e-8) continue;
213589
215870
  const cornersPdfX = [e, a3 + e, a3 + c4 + e, c4 + e];
213590
215871
  const cornersPdfY = [f2, b3 + f2, b3 + d2 + f2, d2 + f2];
213591
- const cornersPx = cornersPdfX.map((cx) => cx * scale2);
213592
- const cornersPy = cornersPdfY.map((cy) => (displayList.height - cy) * scale2);
213593
- const clipMinPx = img.clipRect ? Math.floor(img.clipRect[0] * scale2) : 0;
213594
- const clipMaxPx = img.clipRect ? Math.ceil(img.clipRect[2] * scale2) - 1 : width2 - 1;
213595
- const clipMinPy = img.clipRect ? Math.floor((displayList.height - img.clipRect[3]) * scale2) : 0;
213596
- const clipMaxPy = img.clipRect ? Math.ceil((displayList.height - img.clipRect[1]) * scale2) - 1 : height - 1;
215872
+ const cornersPx = cornersPdfX.map((cx) => (cx - originX) * scale2);
215873
+ const cornersPy = cornersPdfY.map((cy) => (pageTop - cy) * scale2);
215874
+ const clipMinPx = img.clipRect ? Math.floor((img.clipRect[0] - originX) * scale2) : 0;
215875
+ const clipMaxPx = img.clipRect ? Math.ceil((img.clipRect[2] - originX) * scale2) - 1 : width2 - 1;
215876
+ const clipMinPy = img.clipRect ? Math.floor((pageTop - img.clipRect[3]) * scale2) : 0;
215877
+ const clipMaxPy = img.clipRect ? Math.ceil((pageTop - img.clipRect[1]) * scale2) - 1 : height - 1;
213597
215878
  const minPx = Math.max(0, clipMinPx, Math.floor(Math.min(...cornersPx)));
213598
215879
  const maxPx = Math.min(width2 - 1, clipMaxPx, Math.ceil(Math.max(...cornersPx)) - 1);
213599
215880
  const minPy = Math.max(0, clipMinPy, Math.floor(Math.min(...cornersPy)));
@@ -213610,11 +215891,11 @@ function renderDisplayListToBitmap(displayList, options = {}) {
213610
215891
  const smooth = Math.fround((s1 + s2 + Math.hypot(s1 - s2, 2 * cross)) / 2) <= 1;
213611
215892
  const sample2 = new Float64Array(4);
213612
215893
  for (let py = minPy; py <= maxPy; py++) {
213613
- const yPdf = displayList.height - (py + 0.5) / scale2;
215894
+ const yPdf = pageTop - (py + 0.5) / scale2;
213614
215895
  if (img.clipRect && (yPdf < img.clipRect[1] || yPdf > img.clipRect[3])) continue;
213615
215896
  const dyPdf = yPdf - f2;
213616
215897
  for (let px = minPx; px <= maxPx; px++) {
213617
- const xPdf = (px + 0.5) / scale2;
215898
+ const xPdf = originX + (px + 0.5) / scale2;
213618
215899
  if (img.clipRect && (xPdf < img.clipRect[0] || xPdf > img.clipRect[2])) continue;
213619
215900
  const dxPdf = xPdf - e;
213620
215901
  const u = (d2 * dxPdf - c4 * dyPdf) / det;
@@ -213675,6 +215956,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
213675
215956
  }
213676
215957
  result2 = { width: targetW, height: targetH, data: resampled };
213677
215958
  }
215959
+ if (options.useCropBox) {
215960
+ const box = getDisplayListCropBox(displayList);
215961
+ result2 = cropRgbaBitmap(result2, {
215962
+ x: box[0] * scaleX,
215963
+ y: (displayList.height - box[3]) * scaleY,
215964
+ width: (box[2] - box[0]) * scaleX,
215965
+ height: (box[3] - box[1]) * scaleY
215966
+ });
215967
+ }
213678
215968
  result2 = rotateRgbaBitmapQuarterTurns(result2, displayList.rotation ?? 0);
213679
215969
  if (options.cropRect) {
213680
215970
  result2 = cropRgbaBitmap(result2, options.cropRect);
@@ -213703,23 +215993,6 @@ function collectLeavesForRaster(cosDoc, node3, out = [], visited = /* @__PURE__
213703
215993
  }
213704
215994
  return out;
213705
215995
  }
213706
- function extractBoxArray(cosDoc, dict, key) {
213707
- let cur = dict;
213708
- const visited = /* @__PURE__ */ new Set();
213709
- while (cur && !visited.has(cur)) {
213710
- visited.add(cur);
213711
- const arr = cosDoc.resolveArray(dictGet(cur, key));
213712
- if (arr && arr.items.length >= 4) {
213713
- const nums = arr.items.slice(0, 4).map((item) => {
213714
- const r = cosDoc.resolve(item);
213715
- return r?.kind === "number" ? r.value : 0;
213716
- });
213717
- return [nums[0], nums[1], nums[2], nums[3]];
213718
- }
213719
- cur = cosDoc.resolveDict(dictGet(cur, "Parent"));
213720
- }
213721
- return void 0;
213722
- }
213723
215996
  function renderPdfPageToBitmap(pdfBytes, pageIndex = 0, options) {
213724
215997
  const cos = pdfBytes instanceof Uint8Array ? parseCosDocument(pdfBytes) : pdfBytes;
213725
215998
  const catalog = cos.resolveDict(cos.rootRef);
@@ -213728,35 +216001,7 @@ function renderPdfPageToBitmap(pdfBytes, pageIndex = 0, options) {
213728
216001
  if (!leaf) throw new Error(`Page index ${pageIndex} out of bounds`);
213729
216002
  const resolvedIndex = leaves.indexOf(leaf);
213730
216003
  const page = new PdfPage(cos, leaf.ref, leaf.dict, resolvedIndex);
213731
- const { cropRect, ...restOptions } = options ?? {};
213732
- let bitmap = renderDisplayListToBitmap(
213733
- // CropBox is in unrotated page coordinates. Apply page rotation after it.
213734
- { ...page.evaluateDisplayList({ hideAnnotations: options?.hideAnnotations }), rotation: 0 },
213735
- restOptions
213736
- );
213737
- if (options?.useCropBox) {
213738
- const cropBox = extractBoxArray(cos, leaf.dict, "CropBox");
213739
- if (cropBox) {
213740
- const mediaBox = extractBoxArray(cos, leaf.dict, "MediaBox") ?? [0, 0, page.getSize().width, page.getSize().height];
213741
- const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
213742
- const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
213743
- const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
213744
- const mediaH = mediaBox[3] - mediaBox[1];
213745
- const bx = Math.round((cropBox[0] - mediaBox[0]) * scaleX);
213746
- const by = Math.round((mediaH - (cropBox[3] - mediaBox[1])) * scaleY);
213747
- const bw = Math.max(1, Math.round(Math.abs(cropBox[2] - cropBox[0]) * scaleX));
213748
- const bh = Math.max(1, Math.round(Math.abs(cropBox[3] - cropBox[1]) * scaleY));
213749
- bitmap = cropRgbaBitmap(bitmap, { x: bx, y: by, width: bw, height: bh });
213750
- }
213751
- }
213752
- const rotation = page.getRotation();
213753
- if (rotation === 90 || rotation === 180 || rotation === 270) {
213754
- bitmap = rotateRgbaBitmapQuarterTurns(bitmap, rotation);
213755
- }
213756
- if (cropRect) {
213757
- bitmap = cropRgbaBitmap(bitmap, cropRect);
213758
- }
213759
- return bitmap;
216004
+ return page.renderToBitmap(options);
213760
216005
  }
213761
216006
  function renderPdfPageToPng(pdfBytes, pageIndex = 0, options) {
213762
216007
  const bmp = renderPdfPageToBitmap(pdfBytes, pageIndex, options);