Files
marco/release/assets/image-processor-TE4QOxly.js
T
raucao 387fd6efed
CI / Lint (push) Successful in 53s
CI / Test (push) Successful in 1m4s
1.26.0
2026-08-07 07:33:52 -06:00

183 lines
4.3 KiB
JavaScript

var q = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"#",
"$",
"%",
"*",
"+",
",",
"-",
".",
":",
";",
"=",
"?",
"@",
"[",
"]",
"^",
"_",
"{",
"|",
"}",
"~"
], p = (t, e) => {
var a = "";
for (let o = 1; o <= e; o++) {
let h = Math.floor(t) / Math.pow(83, e - o) % 83;
a += q[Math.floor(h)];
}
return a;
}, f = (t) => {
let e = t / 255;
return e <= .04045 ? e / 12.92 : Math.pow((e + .055) / 1.055, 2.4);
}, h = (t) => {
let e = Math.max(0, Math.min(1, t));
return e <= .0031308 ? Math.trunc(12.92 * e * 255 + .5) : Math.trunc(255 * (1.055 * Math.pow(e, .4166666666666667) - .055) + .5);
}, M = (t, e) => ((t) => t < 0 ? -1 : 1)(t) * Math.pow(Math.abs(t), e), d = class extends Error {
constructor(t) {
super(t), this.name = "ValidationError", this.message = t;
}
}, D = (t, e, a, o) => {
let h = 0, r = 0, n = 0, i = 4 * e;
for (let l = 0; l < e; l++) {
let e = 4 * l;
for (let s = 0; s < a; s++) {
let a = e + s * i, g = o(l, s);
h += g * f(t[a]), r += g * f(t[a + 1]), n += g * f(t[a + 2]);
}
}
let s = 1 / (e * a);
return [
h * s,
r * s,
n * s
];
}, S = (t, e, a, o, r) => {
if (o < 1 || o > 9 || r < 1 || r > 9) throw new d("BlurHash must have between 1 and 9 components");
if (e * a * 4 !== t.length) throw new d("Width and height must match the pixels array");
let n = [];
for (let h = 0; h < r; h++) for (let r = 0; r < o; r++) {
let o = 0 == r && 0 == h ? 1 : 2, i = D(t, e, a, (t, n) => o * Math.cos(Math.PI * r * t / e) * Math.cos(Math.PI * h * n / a));
n.push(i);
}
let i, s = n[0], l = n.slice(1), g = "";
if (g += p(o - 1 + 9 * (r - 1), 1), l.length > 0) {
let t = Math.max(...l.map((t) => Math.max(...t))), e = Math.floor(Math.max(0, Math.min(82, Math.floor(166 * t - .5))));
i = (e + 1) / 166, g += p(e, 1);
} else i = 1, g += p(0, 1);
return g += p(((t) => (h(t[0]) << 16) + (h(t[1]) << 8) + h(t[2]))(s), 4), l.forEach((t) => {
g += p(((t, e) => 19 * Math.floor(Math.max(0, Math.min(18, Math.floor(9 * M(t[0] / e, .5) + 9.5)))) * 19 + 19 * Math.floor(Math.max(0, Math.min(18, Math.floor(9 * M(t[1] / e, .5) + 9.5)))) + Math.floor(Math.max(0, Math.min(18, Math.floor(9 * M(t[2] / e, .5) + 9.5)))))(t, i), 2);
}), g;
};
self.onmessage = async (t) => {
if ("PROCESS_IMAGE" !== t.data?.type) return;
const { id: e, file: a, targetWidth: o, targetHeight: h, quality: r, computeBlurhash: n } = t.data;
try {
let t, l;
try {
const e = await createImageBitmap(a, {
resizeWidth: o,
resizeHeight: h,
resizeQuality: "high"
});
if (t = new OffscreenCanvas(o, h), l = t.getContext("2d"), !l) throw new Error("Failed to get 2d context from OffscreenCanvas");
l.drawImage(e, 0, 0, o, h), e.close();
} catch (i) {
console.warn("Hardware resize failed, falling back to stepped software scaling:", i);
const e = await a.arrayBuffer(), r = new Blob([e], { type: a.type }), n = await createImageBitmap(r);
let s = n.width, g = n.height, f = new OffscreenCanvas(s, g), c = f.getContext("2d");
for (c.imageSmoothingEnabled = !0, c.imageSmoothingQuality = "high", c.drawImage(n, 0, 0); .5 * f.width > o && .5 * f.height > h;) {
const t = new OffscreenCanvas(Math.floor(.5 * f.width), Math.floor(.5 * f.height)), e = t.getContext("2d");
e.imageSmoothingEnabled = !0, e.imageSmoothingQuality = "high", e.drawImage(f, 0, 0, t.width, t.height), f = t;
}
t = new OffscreenCanvas(o, h), l = t.getContext("2d"), l.imageSmoothingEnabled = !0, l.imageSmoothingQuality = "high", l.drawImage(f, 0, 0, o, h), n.close();
}
let g = null;
if (n) try {
const t = l.getImageData(0, 0, o, h);
g = S(t.data, o, h, 4, 3);
} catch (s) {
console.warn("Could not generate blurhash (possible canvas fingerprinting protection):", s);
}
const f = await t.convertToBlob({
type: "image/jpeg",
quality: r
}), c = `${o}x${h}`;
self.postMessage({
id: e,
success: !0,
blob: f,
dim: c,
blurhash: g
});
} catch (l) {
self.postMessage({
id: e,
success: !1,
error: l.message
});
}
};