emf-converter 4.8.5 → 4.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.mjs CHANGED
@@ -16532,153 +16532,26 @@ function applyTint(src, hue, amount) {
16532
16532
  var TINT_FULL = 254;
16533
16533
  function applyRedEyeCorrection(src, width, height, areas) {
16534
16534
  const out = new Uint8ClampedArray(src);
16535
+ const carry = { x: 0, y: 0 };
16535
16536
  for (const a of areas) {
16536
- correctRedEyeArea(out, width, clamp(a.left, 0, width), clamp(a.top, 0, height), clamp(a.right, 0, width), clamp(a.bottom, 0, height));
16537
+ correctRedEyeArea(out, width, clamp(a.left, 0, width), clamp(a.top, 0, height), clamp(a.right, 0, width), clamp(a.bottom, 0, height), carry);
16537
16538
  }
16538
16539
  return out;
16539
16540
  }
16540
- var RED_EYE_FALLOFF = new Float64Array(
16541
- [
16542
- 24930,
16543
- 24570,
16544
- 24201,
16545
- 23836,
16546
- 23471,
16547
- 23107,
16548
- 22744,
16549
- 22367,
16550
- 21976,
16551
- 21587,
16552
- 21198,
16553
- 20824,
16554
- 20490,
16555
- 20165,
16556
- 19832,
16557
- 19499,
16558
- 19157,
16559
- 18817,
16560
- 18480,
16561
- 18151,
16562
- 17820,
16563
- 17490,
16564
- 17160,
16565
- 16831,
16566
- 16506,
16567
- 16189,
16568
- 15878,
16569
- 15569,
16570
- 15273,
16571
- 14973,
16572
- 14668,
16573
- 14362,
16574
- 14059,
16575
- 13768,
16576
- 13484,
16577
- 13203,
16578
- 12923,
16579
- 12642,
16580
- 12366,
16581
- 12094,
16582
- 11828,
16583
- 11564,
16584
- 11301,
16585
- 11034,
16586
- 10770,
16587
- 10507,
16588
- 10253,
16589
- 10011,
16590
- 9771,
16591
- 9530,
16592
- 9290,
16593
- 9053,
16594
- 8819,
16595
- 8588,
16596
- 8359,
16597
- 8134,
16598
- 7914,
16599
- 7697,
16600
- 7481,
16601
- 7267,
16602
- 7056,
16603
- 6851,
16604
- 6651,
16605
- 6453,
16606
- 6256,
16607
- 6061,
16608
- 5871,
16609
- 5684,
16610
- 5499,
16611
- 5317,
16612
- 5138,
16613
- 4962,
16614
- 4789,
16615
- 4619,
16616
- 4452,
16617
- 4289,
16618
- 4130,
16619
- 3974,
16620
- 3820,
16621
- 3669,
16622
- 3520,
16623
- 3375,
16624
- 3232,
16625
- 3093,
16626
- 2958,
16627
- 2825,
16628
- 2695,
16629
- 2568,
16630
- 2444,
16631
- 2325,
16632
- 2207,
16633
- 2092,
16634
- 1980,
16635
- 1872,
16636
- 1768,
16637
- 1666,
16638
- 1567,
16639
- 1470,
16640
- 1377,
16641
- 1287,
16642
- 1200,
16643
- 1116,
16644
- 1034,
16645
- 956,
16646
- 881,
16647
- 808,
16648
- 739,
16649
- 674,
16650
- 612,
16651
- 541,
16652
- 462,
16653
- 381,
16654
- 299,
16655
- 220,
16656
- 147,
16657
- 85,
16658
- 36,
16659
- 3,
16660
- 0
16661
- ].map((v) => v / 1e5)
16662
- );
16663
- function redEyeFalloff(u) {
16664
- const t = u * 128;
16665
- const i = Math.floor(t);
16666
- if (i >= RED_EYE_FALLOFF.length - 1) {
16667
- return 0;
16668
- }
16669
- return RED_EYE_FALLOFF[i] + (t - i) * (RED_EYE_FALLOFF[i + 1] - RED_EYE_FALLOFF[i]);
16670
- }
16671
16541
  var RED_EYE_SECTORS = 60;
16672
16542
  var RED_EYE_BLUE_WEIGHT = 0.225;
16673
- var RED_EYE_WEIGHT_CAP = 6;
16674
- var RED_EYE_PURE_WEIGHT = RED_EYE_WEIGHT_CAP;
16675
- var RED_EYE_DARK_STRENGTH = 0.49;
16676
- var RED_EYE_DARK_RATIO = 0.6;
16677
- var RED_EYE_GREEN_SHARE = 80 / 255;
16678
- function correctRedEyeArea(out, stride, x0, y0, x1, y1) {
16543
+ var RED_EYE_PURE_WEIGHT = 1 / (1 + RED_EYE_BLUE_WEIGHT);
16544
+ var RED_EYE_CARRY = 0.81;
16545
+ var RED_EYE_GREEN_SHARE = 5 / 16;
16546
+ var RED_EYE_SPREAD_STEPS = [31.5, 50, 98.78];
16547
+ var RED_EYE_STRENGTHS = [0.25, 0.5, 0.661, 0.75];
16548
+ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
16679
16549
  const w = x1 - x0;
16680
16550
  const h = y1 - y0;
16681
16551
  const count = w * h;
16552
+ if (!(count > 0)) {
16553
+ return;
16554
+ }
16682
16555
  const redness = new Float64Array(count);
16683
16556
  const dark = new Float64Array(count);
16684
16557
  let sx = 0;
@@ -16691,34 +16564,44 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1) {
16691
16564
  const g = out[i + 1];
16692
16565
  const b = out[i + 2];
16693
16566
  const k = y * w + x;
16694
- dark[k] = Math.min(g, b);
16567
+ const d = g + RED_EYE_BLUE_WEIGHT * b;
16568
+ dark[k] = d;
16695
16569
  const v = r - Math.max(g, b);
16696
16570
  if (v > 0) {
16697
16571
  redness[k] = v;
16698
- const denominator = g + RED_EYE_BLUE_WEIGHT * b;
16699
- {
16700
- const weight = denominator >= 1 ? Math.min(RED_EYE_WEIGHT_CAP, v / denominator) : RED_EYE_PURE_WEIGHT;
16701
- sx += weight * (x + 0.5);
16702
- sy += weight * (y + 0.5);
16703
- sw += weight;
16704
- }
16572
+ const weight = d >= 1 ? v / d : RED_EYE_PURE_WEIGHT;
16573
+ sx += weight * (x + 0.5);
16574
+ sy += weight * (y + 0.5);
16575
+ sw += weight;
16705
16576
  }
16706
16577
  }
16707
16578
  }
16708
16579
  if (sw === 0) {
16709
- if (!redness.some((v) => v > 0)) {
16710
- return;
16711
- }
16712
- sx = w / 2;
16713
- sy = h / 2;
16714
- sw = 1;
16580
+ return;
16715
16581
  }
16716
- const cx = sx / sw;
16717
- const cy = sy / sw;
16718
- const radius = Math.min(cx, cy) - 0.5;
16582
+ let cx = (sx + RED_EYE_CARRY * carry.x) / sw;
16583
+ let cy = (sy + RED_EYE_CARRY * carry.y) / sw;
16584
+ carry.x = x0 + cx;
16585
+ carry.y = y0 + cy;
16586
+ if (Math.hypot(cx - w / 2, cy - h / 2) >= Math.max(Math.min(w, h) / 2, (w + h) / 6)) {
16587
+ cx = w / 2;
16588
+ cy = h / 2;
16589
+ }
16590
+ const ax = x0 + cx;
16591
+ const ay = y0 + cy;
16592
+ const edgeX = Math.round(cx) > w / 2 ? w - cx + 0.5 : cx - 0.5;
16593
+ const edgeY = Math.round(cy) > h / 2 ? h - cy + 0.5 : cy - 0.5;
16594
+ const radius = ax > ay ? Math.min(edgeX, ay - 0.5) : Math.min(edgeY, ax - 0.5);
16719
16595
  if (!(radius > 0)) {
16720
16596
  return;
16721
16597
  }
16598
+ const sorted = Float64Array.from(dark).sort();
16599
+ const spread = sorted[Math.floor(0.7 * count)] - sorted[Math.floor(0.3 * count)];
16600
+ let level = 0;
16601
+ while (level < RED_EYE_SPREAD_STEPS.length && spread >= RED_EYE_SPREAD_STEPS[level]) {
16602
+ level++;
16603
+ }
16604
+ const strength = RED_EYE_STRENGTHS[level];
16722
16605
  const sector = new Uint8Array(count);
16723
16606
  const distance = new Float64Array(count);
16724
16607
  const sectorSum = new Float64Array(RED_EYE_SECTORS);
@@ -16756,7 +16639,8 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1) {
16756
16639
  const mean = sectorSum[s] / sectorCount[s];
16757
16640
  const meanDark = sectorDark[s] / sectorCount[s];
16758
16641
  const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
16759
- const falloff = Math.max(redEyeFalloff(distance[k] / radius), RED_EYE_DARK_STRENGTH * Math.max(0, 1 - ratio / RED_EYE_DARK_RATIO));
16642
+ const u = distance[k] / radius;
16643
+ const falloff = Math.max(strength * (1 - u) * (1 - u), 0.5 * Math.max(0, 1 - ratio) ** 2);
16760
16644
  const rest = (1 - falloff) * mean;
16761
16645
  if (rest >= v) {
16762
16646
  continue;
@@ -31932,40 +31816,121 @@ function halftoneReduceTaps(srcLen, dstLen, reverse) {
31932
31816
  if (reverse) taps.reverse();
31933
31817
  return taps;
31934
31818
  }
31935
- var ENLARGE_KERNEL = [
31936
- 0.7598,
31937
- 0.7276,
31938
- 0.6829,
31939
- 0.6528,
31940
- 0.6106,
31941
- 0.5745,
31942
- 0.5362,
31943
- 0.4955,
31944
- 0.457,
31945
- 0.4121,
31946
- 0.3762,
31947
- 0.3233,
31948
- 0.2741,
31949
- 0.226,
31950
- 0.1822,
31951
- 0.1412,
31952
- 0.1021,
31953
- 0.0685,
31954
- 0.0382,
31955
- 0.0138,
31819
+ var ENLARGE_INNER = [
31820
+ 1e3,
31821
+ 992.47,
31822
+ 984.9399,
31823
+ 977.4099,
31824
+ 969.8798,
31825
+ 962.3498,
31826
+ 954.8198,
31827
+ 947.2897,
31828
+ 939.7597,
31829
+ 932.2296,
31830
+ 924.6996,
31831
+ 917.1695,
31832
+ 909.6395,
31833
+ 902.1095,
31834
+ 894.5665,
31835
+ 886.8087,
31836
+ 879.045,
31837
+ 871.2813,
31838
+ 863.4349,
31839
+ 855.5885,
31840
+ 847.7421,
31841
+ 839.8269,
31842
+ 831.9046,
31843
+ 823.912,
31844
+ 815.9193,
31845
+ 807.9266,
31846
+ 799.847,
31847
+ 791.7283,
31848
+ 783.6096,
31849
+ 775.449,
31850
+ 767.3204,
31851
+ 758.9233,
31852
+ 750.5263,
31853
+ 742.4271,
31854
+ 734.0547,
31855
+ 725.6823,
31856
+ 717.232,
31857
+ 708.7675,
31858
+ 700.2393,
31859
+ 691.7111,
31860
+ 683.0734,
31861
+ 674.4357,
31862
+ 665.7105,
31863
+ 656.9854,
31864
+ 648.2603,
31865
+ 639.3747,
31866
+ 630.4873,
31867
+ 621.5157,
31868
+ 612.5442
31869
+ ];
31870
+ var ENLARGE_OUTER = [
31871
+ 375.1388,
31872
+ 364.2093,
31873
+ 353.2797,
31874
+ 342.4714,
31875
+ 331.7615,
31876
+ 321.1462,
31877
+ 310.6456,
31878
+ 300.2252,
31879
+ 289.9229,
31880
+ 279.7227,
31881
+ 269.6439,
31882
+ 259.6535,
31883
+ 249.7825,
31884
+ 240.0362,
31885
+ 230.3856,
31886
+ 220.8799,
31887
+ 211.4594,
31888
+ 202.1844,
31889
+ 192.9996,
31890
+ 183.9679,
31891
+ 175.1064,
31892
+ 166.2864,
31893
+ 157.6436,
31894
+ 149.1447,
31895
+ 140.7609,
31896
+ 132.5474,
31897
+ 124.4802,
31898
+ 116.5636,
31899
+ 108.778,
31900
+ 101.1602,
31901
+ 93.7098,
31902
+ 86.4419,
31903
+ 79.3251,
31904
+ 72.4091,
31905
+ 65.6853,
31906
+ 59.1472,
31907
+ 52.812,
31908
+ 46.6978,
31909
+ 40.8001,
31910
+ 35.1449,
31911
+ 29.7494,
31912
+ 24.6096,
31913
+ 19.7977,
31914
+ 15.2801,
31915
+ 11.1442,
31916
+ 7.3916,
31917
+ 4.1415,
31918
+ 1.4039,
31956
31919
  0
31957
31920
  ];
31958
- var ENLARGE_BOX = 0.2429;
31959
- var ENLARGE_STEP = 0.05;
31921
+ var ENLARGE_HALF = 500.0106;
31922
+ var ENLARGE_KNOTS = 96;
31960
31923
  function enlargeKernel(u) {
31961
- const edge = u / ENLARGE_STEP;
31962
- const i = Math.floor(edge);
31963
- const smooth = i >= ENLARGE_KERNEL.length - 1 ? 0 : ENLARGE_KERNEL[i] + (ENLARGE_KERNEL[i + 1] - ENLARGE_KERNEL[i]) * (edge - i);
31964
- return smooth + ENLARGE_BOX * (Math.abs(u - 0.5) < 1e-9 ? 0.5 : u < 0.5 ? 1 : 0);
31924
+ if (u >= 1) return 0;
31925
+ if (Math.abs(u - 0.5) < 1e-9) return ENLARGE_HALF;
31926
+ const table = u < 0.5 ? ENLARGE_INNER : ENLARGE_OUTER;
31927
+ const edge = u * ENLARGE_KNOTS - (u < 0.5 ? 0 : ENLARGE_KNOTS / 2);
31928
+ const i = Math.min(table.length - 2, Math.floor(edge + 1e-9));
31929
+ return table[i] + (table[i + 1] - table[i]) * (edge - i);
31965
31930
  }
31966
31931
  function halftoneEnlargeTaps(src, dst) {
31967
31932
  const ratio = dst / src;
31968
- const reach = Math.ceil((ENLARGE_KERNEL.length - 1) * ENLARGE_STEP * ratio);
31933
+ const reach = Math.ceil(ratio) - 1;
31969
31934
  const fir = [];
31970
31935
  let total = 0;
31971
31936
  for (let k = 0; k <= reach; k++) {
@@ -31994,7 +31959,17 @@ function halftoneEnlargeTaps(src, dst) {
31994
31959
  weights.set(j, (weights.get(j) ?? 0) + w * v);
31995
31960
  }
31996
31961
  }
31997
- taps.push([...weights.entries()]);
31962
+ const sorted = [...weights.entries()].sort((a, b) => a[0] - b[0]);
31963
+ let prev = 0;
31964
+ let cum = 0;
31965
+ const row2 = [];
31966
+ for (let i = 0; i < sorted.length; i++) {
31967
+ cum += sorted[i][1] * 8192;
31968
+ const c = i === sorted.length - 1 ? 8192 : Math.ceil(cum - 1e-7);
31969
+ row2.push([sorted[i][0], (c - prev) / 8192]);
31970
+ prev = c;
31971
+ }
31972
+ taps.push(row2);
31998
31973
  }
31999
31974
  return taps;
32000
31975
  }
@@ -32211,8 +32186,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
32211
32186
  const sampleW = nativeMixed ? Math.min(SW, W) : W;
32212
32187
  const sampleH = nativeMixed ? Math.min(SH, H) : H;
32213
32188
  const axis = nativeMixed ? (n, d, r) => halftoneReduceTaps(n, d, r) : (n, d, r) => halftoneAxis(0, n, d, r);
32214
- const cols = axis(SW, sampleW, flipX);
32215
- const rows = axis(SH, sampleH, flipY);
32189
+ const enlargeX = nativeMixed && W > SW;
32190
+ const enlargeY = nativeMixed && H > SH;
32191
+ const cols = axis(SW, sampleW, flipX && !enlargeX);
32192
+ const rows = axis(SH, sampleH, flipY && !enlargeY);
32216
32193
  if (nearestMixed) {
32217
32194
  const nearest = (taps, src2, dst, reverse) => {
32218
32195
  for (let i = 0; i < dst; i++) {
@@ -32321,6 +32298,8 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
32321
32298
  return halftoneEnlargeTaps(src2, dst);
32322
32299
  };
32323
32300
  const xt = axisTaps(sampleW, W), yt = axisTaps(sampleH, H);
32301
+ if (enlargeX && flipX) xt.reverse();
32302
+ if (enlargeY && flipY) yt.reverse();
32324
32303
  for (let y = 0; y < H; y++) {
32325
32304
  for (let x = 0; x < W; x++) {
32326
32305
  for (let c = 0; c < 3; c++) {