Replace CDN React/ReactDOM/Babel with local libs; remove Babel and inline scripts Build Tailwind locally, add safelist; switch to assets/tailwind.css Self-host Font Awesome and Inter (CSS + woff2); remove external font CDNs Implement strict CSP (no unsafe-inline/eval; scripts/styles/fonts from self) Extract inline handlers; move PWA scripts to external files Add local QR code generation (qrcode lib) and remove api.qrserver.com Improve SessionTypeSelector visual selection (highlighted background and ring) Keep PWA working with service worker and offline assets Refs: CSP hardening, offline-first, no external dependencies
94 lines
2.3 KiB
JavaScript
94 lines
2.3 KiB
JavaScript
"use strict";
|
|
|
|
function dePalette(indata, outdata, width, height, palette) {
|
|
let pxPos = 0;
|
|
// use values from palette
|
|
for (let y = 0; y < height; y++) {
|
|
for (let x = 0; x < width; x++) {
|
|
let color = palette[indata[pxPos]];
|
|
|
|
if (!color) {
|
|
throw new Error("index " + indata[pxPos] + " not in palette");
|
|
}
|
|
|
|
for (let i = 0; i < 4; i++) {
|
|
outdata[pxPos + i] = color[i];
|
|
}
|
|
pxPos += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
function replaceTransparentColor(indata, outdata, width, height, transColor) {
|
|
let pxPos = 0;
|
|
for (let y = 0; y < height; y++) {
|
|
for (let x = 0; x < width; x++) {
|
|
let makeTrans = false;
|
|
|
|
if (transColor.length === 1) {
|
|
if (transColor[0] === indata[pxPos]) {
|
|
makeTrans = true;
|
|
}
|
|
} else if (
|
|
transColor[0] === indata[pxPos] &&
|
|
transColor[1] === indata[pxPos + 1] &&
|
|
transColor[2] === indata[pxPos + 2]
|
|
) {
|
|
makeTrans = true;
|
|
}
|
|
if (makeTrans) {
|
|
for (let i = 0; i < 4; i++) {
|
|
outdata[pxPos + i] = 0;
|
|
}
|
|
}
|
|
pxPos += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
function scaleDepth(indata, outdata, width, height, depth) {
|
|
let maxOutSample = 255;
|
|
let maxInSample = Math.pow(2, depth) - 1;
|
|
let pxPos = 0;
|
|
|
|
for (let y = 0; y < height; y++) {
|
|
for (let x = 0; x < width; x++) {
|
|
for (let i = 0; i < 4; i++) {
|
|
outdata[pxPos + i] = Math.floor(
|
|
(indata[pxPos + i] * maxOutSample) / maxInSample + 0.5
|
|
);
|
|
}
|
|
pxPos += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = function (indata, imageData) {
|
|
let depth = imageData.depth;
|
|
let width = imageData.width;
|
|
let height = imageData.height;
|
|
let colorType = imageData.colorType;
|
|
let transColor = imageData.transColor;
|
|
let palette = imageData.palette;
|
|
|
|
let outdata = indata; // only different for 16 bits
|
|
|
|
if (colorType === 3) {
|
|
// paletted
|
|
dePalette(indata, outdata, width, height, palette);
|
|
} else {
|
|
if (transColor) {
|
|
replaceTransparentColor(indata, outdata, width, height, transColor);
|
|
}
|
|
// if it needs scaling
|
|
if (depth !== 8) {
|
|
// if we need to change the buffer size
|
|
if (depth === 16) {
|
|
outdata = Buffer.alloc(width * height * 4);
|
|
}
|
|
scaleDepth(indata, outdata, width, height, depth);
|
|
}
|
|
}
|
|
return outdata;
|
|
};
|