mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Replace png encode dependency with optimized CRC32 calculation
This commit is contained in:
43
package-lock.json
generated
43
package-lock.json
generated
@ -48,6 +48,7 @@
|
|||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"cookie-session": "^2.1.0",
|
"cookie-session": "^2.1.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"crc": "^4.3.2",
|
||||||
"csrf-sync": "^4.0.3",
|
"csrf-sync": "^4.0.3",
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
"dompurify": "^3.2.4",
|
"dompurify": "^3.2.4",
|
||||||
@ -76,7 +77,6 @@
|
|||||||
"node-persist": "^4.0.4",
|
"node-persist": "^4.0.4",
|
||||||
"open": "^8.4.2",
|
"open": "^8.4.2",
|
||||||
"png-chunk-text": "^1.0.0",
|
"png-chunk-text": "^1.0.0",
|
||||||
"png-chunks-encode": "^1.0.0",
|
|
||||||
"png-chunks-extract": "^1.0.0",
|
"png-chunks-extract": "^1.0.0",
|
||||||
"proxy-agent": "^6.5.0",
|
"proxy-agent": "^6.5.0",
|
||||||
"rate-limiter-flexible": "^5.0.5",
|
"rate-limiter-flexible": "^5.0.5",
|
||||||
@ -121,7 +121,6 @@
|
|||||||
"@types/node": "^18.19.80",
|
"@types/node": "^18.19.80",
|
||||||
"@types/node-persist": "^3.1.8",
|
"@types/node-persist": "^3.1.8",
|
||||||
"@types/png-chunk-text": "^1.0.3",
|
"@types/png-chunk-text": "^1.0.3",
|
||||||
"@types/png-chunks-encode": "^1.0.2",
|
|
||||||
"@types/png-chunks-extract": "^1.0.2",
|
"@types/png-chunks-extract": "^1.0.2",
|
||||||
"@types/response-time": "^2.3.8",
|
"@types/response-time": "^2.3.8",
|
||||||
"@types/select2": "^4.0.63",
|
"@types/select2": "^4.0.63",
|
||||||
@ -2033,13 +2032,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/png-chunks-encode": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/png-chunks-encode/-/png-chunks-encode-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-Dxn0aXEcSg1wVeHjvNlygm/+fKBDzWMCdxJYhjGUTeefFW/jYxWcrg+W7ppLBfH44iJMqeVBHtHBwtYQUeYvgw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/png-chunks-extract": {
|
"node_modules/@types/png-chunks-extract": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/png-chunks-extract/-/png-chunks-extract-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/png-chunks-extract/-/png-chunks-extract-1.0.2.tgz",
|
||||||
@ -3542,6 +3534,23 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crc": {
|
||||||
|
"version": "4.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz",
|
||||||
|
"integrity": "sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"buffer": ">=6.0.3"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"buffer": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/crc-32": {
|
"node_modules/crc-32": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-0.3.0.tgz",
|
||||||
@ -6686,16 +6695,6 @@
|
|||||||
"integrity": "sha512-DEROKU3SkkLGWNMzru3xPVgxyd48UGuMSZvioErCure6yhOc/pRH2ZV+SEn7nmaf7WNf3NdIpH+UTrRdKyq9Lw==",
|
"integrity": "sha512-DEROKU3SkkLGWNMzru3xPVgxyd48UGuMSZvioErCure6yhOc/pRH2ZV+SEn7nmaf7WNf3NdIpH+UTrRdKyq9Lw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/png-chunks-encode": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/png-chunks-encode/-/png-chunks-encode-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-J1jcHgbQRsIIgx5wxW9UmCymV3wwn4qCCJl6KYgEU/yHCh/L2Mwq/nMOkRPtmV79TLxRZj5w3tH69pvygFkDqA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"crc-32": "^0.3.0",
|
|
||||||
"sliced": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/png-chunks-extract": {
|
"node_modules/png-chunks-extract": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/png-chunks-extract/-/png-chunks-extract-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/png-chunks-extract/-/png-chunks-extract-1.0.0.tgz",
|
||||||
@ -7532,12 +7531,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/sliced": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/slidetoggle": {
|
"node_modules/slidetoggle": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/slidetoggle/-/slidetoggle-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/slidetoggle/-/slidetoggle-4.0.0.tgz",
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"cookie-session": "^2.1.0",
|
"cookie-session": "^2.1.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"crc": "^4.3.2",
|
||||||
"csrf-sync": "^4.0.3",
|
"csrf-sync": "^4.0.3",
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
"dompurify": "^3.2.4",
|
"dompurify": "^3.2.4",
|
||||||
@ -66,7 +67,6 @@
|
|||||||
"node-persist": "^4.0.4",
|
"node-persist": "^4.0.4",
|
||||||
"open": "^8.4.2",
|
"open": "^8.4.2",
|
||||||
"png-chunk-text": "^1.0.0",
|
"png-chunk-text": "^1.0.0",
|
||||||
"png-chunks-encode": "^1.0.0",
|
|
||||||
"png-chunks-extract": "^1.0.0",
|
"png-chunks-extract": "^1.0.0",
|
||||||
"proxy-agent": "^6.5.0",
|
"proxy-agent": "^6.5.0",
|
||||||
"rate-limiter-flexible": "^5.0.5",
|
"rate-limiter-flexible": "^5.0.5",
|
||||||
@ -151,7 +151,6 @@
|
|||||||
"@types/node": "^18.19.80",
|
"@types/node": "^18.19.80",
|
||||||
"@types/node-persist": "^3.1.8",
|
"@types/node-persist": "^3.1.8",
|
||||||
"@types/png-chunk-text": "^1.0.3",
|
"@types/png-chunk-text": "^1.0.3",
|
||||||
"@types/png-chunks-encode": "^1.0.2",
|
|
||||||
"@types/png-chunks-extract": "^1.0.2",
|
"@types/png-chunks-extract": "^1.0.2",
|
||||||
"@types/response-time": "^2.3.8",
|
"@types/response-time": "^2.3.8",
|
||||||
"@types/select2": "^4.0.63",
|
"@types/select2": "^4.0.63",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import { Buffer } from 'node:buffer';
|
import { Buffer } from 'node:buffer';
|
||||||
|
|
||||||
import encode from 'png-chunks-encode';
|
import encode from './png/encode.js';
|
||||||
import extract from 'png-chunks-extract';
|
import extract from 'png-chunks-extract';
|
||||||
import PNGtext from 'png-chunk-text';
|
import PNGtext from 'png-chunk-text';
|
||||||
|
|
||||||
|
68
src/png/encode.js
Normal file
68
src/png/encode.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { crc32 } from 'crc';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes PNG chunks into a PNG file format buffer.
|
||||||
|
* @param {Array<{ name: string; data: Uint8Array }>} chunks Array of PNG chunks
|
||||||
|
* @returns {Uint8Array} Encoded PNG data
|
||||||
|
* @copyright Based on https://github.com/hughsk/png-chunks-encode (MIT)
|
||||||
|
*/
|
||||||
|
export default function encode(chunks) {
|
||||||
|
const uint8 = new Uint8Array(4);
|
||||||
|
const int32 = new Int32Array(uint8.buffer);
|
||||||
|
const uint32 = new Uint32Array(uint8.buffer);
|
||||||
|
|
||||||
|
let totalSize = 8;
|
||||||
|
let idx = totalSize;
|
||||||
|
|
||||||
|
for (let i = 0; i < chunks.length; i++) {
|
||||||
|
totalSize += chunks[i].data.length;
|
||||||
|
totalSize += 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = new Uint8Array(totalSize);
|
||||||
|
|
||||||
|
output[0] = 0x89;
|
||||||
|
output[1] = 0x50;
|
||||||
|
output[2] = 0x4E;
|
||||||
|
output[3] = 0x47;
|
||||||
|
output[4] = 0x0D;
|
||||||
|
output[5] = 0x0A;
|
||||||
|
output[6] = 0x1A;
|
||||||
|
output[7] = 0x0A;
|
||||||
|
|
||||||
|
for (let i = 0; i < chunks.length; i++) {
|
||||||
|
const { name, data } = chunks[i];
|
||||||
|
const size = data.length;
|
||||||
|
const nameChars = [
|
||||||
|
name.charCodeAt(0),
|
||||||
|
name.charCodeAt(1),
|
||||||
|
name.charCodeAt(2),
|
||||||
|
name.charCodeAt(3),
|
||||||
|
];
|
||||||
|
|
||||||
|
uint32[0] = size;
|
||||||
|
output[idx++] = uint8[3];
|
||||||
|
output[idx++] = uint8[2];
|
||||||
|
output[idx++] = uint8[1];
|
||||||
|
output[idx++] = uint8[0];
|
||||||
|
|
||||||
|
output[idx++] = nameChars[0];
|
||||||
|
output[idx++] = nameChars[1];
|
||||||
|
output[idx++] = nameChars[2];
|
||||||
|
output[idx++] = nameChars[3];
|
||||||
|
|
||||||
|
for (let j = 0; j < size;) {
|
||||||
|
output[idx++] = data[j++];
|
||||||
|
}
|
||||||
|
|
||||||
|
const crc = crc32(data, crc32(new Uint8Array(nameChars)));
|
||||||
|
|
||||||
|
int32[0] = crc;
|
||||||
|
output[idx++] = uint8[3];
|
||||||
|
output[idx++] = uint8[2];
|
||||||
|
output[idx++] = uint8[1];
|
||||||
|
output[idx++] = uint8[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
Reference in New Issue
Block a user