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