Some checks failed
test / test (push) Failing after 24s
Реализация целевого дизайна (docs/architecture/target-design.md): - src/: модульная структура (config, logger, errors, http, core: auth/history/jobs/engines/comfy/codex/images) - Очередь заданий: FIFO, кониурентность codex=1 / comfy-upscale=2, MAX_QUEUED_JOBS=5, JSONL-журнал и восстановление после рестарта (running → interrupted, upscale requeue) - Персистентные сессии (sha256-хеши токенов), scrypt-хеш пароля, rate-limit входа, Origin-проверка, magic-byte валидация аплоадов - Атомарная запись манифеста истории, каскадное удаление, URL с фактическим расширением + 302-алиас /image.jpg, миграция history/ → data/history - Даунскейл sharp до 1024px перед Codex + масштабирование области референса - SSE /api/events с фолбэком на polling, фронтенд переведён на ES-модули (public/js/) - Тесты node:test + supertest (27), CI workflow test.yml, Docker/деплой: том kadr-data - Документация: README, docs/architecture/
72 lines
1.5 KiB
JavaScript
72 lines
1.5 KiB
JavaScript
"use strict";
|
|
|
|
const PNG_SIGNATURE = "89504e470d0a1a0a";
|
|
|
|
const HEIC_BRANDS = new Set([
|
|
"heic",
|
|
"heix",
|
|
"hevc",
|
|
"hevx",
|
|
"heim",
|
|
"heis",
|
|
"hevm",
|
|
"hevs",
|
|
"mif1",
|
|
"msf1",
|
|
"heif",
|
|
]);
|
|
|
|
/**
|
|
* Определяет тип изображения по сигнатуре первых байтов (magic bytes).
|
|
* @param {Buffer} buffer
|
|
* @returns {'jpeg' | 'png' | 'webp' | 'heic' | null}
|
|
*/
|
|
function sniffImageType(buffer) {
|
|
if (!Buffer.isBuffer(buffer) || buffer.length < 12) {
|
|
return null;
|
|
}
|
|
|
|
// JPEG: FF D8 FF
|
|
if (buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) {
|
|
return "jpeg";
|
|
}
|
|
|
|
// PNG: 89 50 4E 47 0D 0A 1A 0A
|
|
if (buffer.subarray(0, 8).toString("hex") === PNG_SIGNATURE) {
|
|
return "png";
|
|
}
|
|
|
|
// WebP: RIFF....WEBP
|
|
if (
|
|
buffer.toString("ascii", 0, 4) === "RIFF" &&
|
|
buffer.toString("ascii", 8, 12) === "WEBP"
|
|
) {
|
|
return "webp";
|
|
}
|
|
|
|
// HEIC / HEIF: ftyp box
|
|
if (buffer.toString("ascii", 4, 8) === "ftyp") {
|
|
const majorBrand = buffer.toString("ascii", 8, 12).toLowerCase();
|
|
if (HEIC_BRANDS.has(majorBrand)) {
|
|
return "heic";
|
|
}
|
|
|
|
// Check compatible brands
|
|
const boxLength = buffer.readUInt32BE(0);
|
|
const limit = Math.min(buffer.length, boxLength > 0 ? boxLength : 64);
|
|
for (let offset = 16; offset + 4 <= limit; offset += 4) {
|
|
const brand = buffer.toString("ascii", offset, offset + 4).toLowerCase();
|
|
if (HEIC_BRANDS.has(brand)) {
|
|
return "heic";
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
module.exports = {
|
|
sniffImageType,
|
|
HEIC_BRANDS,
|
|
};
|