🎉 initiate project *astro_rewrite*

This commit is contained in:
sindrekjelsrud 2023-07-19 21:31:30 +02:00
parent ffd4d5e86c
commit 2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions

View file

@ -0,0 +1,3 @@
/// <reference types="node" />
import { type imageType } from './types.js';
export declare function detector(buffer: Buffer): imageType | undefined;

View file

@ -0,0 +1,28 @@
import { typeHandlers } from "./types.js";
const keys = Object.keys(typeHandlers);
const firstBytes = {
56: "psd",
66: "bmp",
68: "dds",
71: "gif",
73: "tiff",
77: "tiff",
82: "webp",
105: "icns",
137: "png",
255: "jpg"
};
function detector(buffer) {
const byte = buffer[0];
if (byte in firstBytes) {
const type = firstBytes[byte];
if (type && typeHandlers[type].validate(buffer)) {
return type;
}
}
const finder = (key) => typeHandlers[key].validate(buffer);
return keys.find(finder);
}
export {
detector
};

View file

@ -0,0 +1,11 @@
/// <reference types="node" />
import { type imageType } from "./types.js";
import type { ISizeCalculationResult } from "./types/interface.js";
type CallbackFn = (e: Error | null, r?: ISizeCalculationResult) => void;
export default imageSize;
export declare function imageSize(input: Buffer | string): ISizeCalculationResult;
export declare function imageSize(input: string, callback: CallbackFn): void;
export declare const disableFS: (v: boolean) => void;
export declare const disableTypes: (types: imageType[]) => void;
export declare const setConcurrency: (c: number) => void;
export declare const types: string[];

View file

@ -0,0 +1,93 @@
import * as fs from "node:fs";
import * as path from "node:path";
import Queue from "../queue/queue.js";
import { detector } from "./detector.js";
import { typeHandlers } from "./types.js";
const MaxBufferSize = 512 * 1024;
const queue = new Queue({ concurrency: 100, autostart: true });
const globalOptions = {
disabledFS: false,
disabledTypes: []
};
function lookup(buffer, filepath) {
const type = detector(buffer);
if (typeof type !== "undefined") {
if (globalOptions.disabledTypes.indexOf(type) > -1) {
throw new TypeError("disabled file type: " + type);
}
if (type in typeHandlers) {
const size = typeHandlers[type].calculate(buffer, filepath);
if (size !== void 0) {
size.type = type;
return size;
}
}
}
throw new TypeError(
"unsupported file type: " + type + " (file: " + filepath + ")"
);
}
async function asyncFileToBuffer(filepath) {
const handle = await fs.promises.open(filepath, "r");
const { size } = await handle.stat();
if (size <= 0) {
await handle.close();
throw new Error("Empty file");
}
const bufferSize = Math.min(size, MaxBufferSize);
const buffer = Buffer.alloc(bufferSize);
await handle.read(buffer, 0, bufferSize, 0);
await handle.close();
return buffer;
}
function syncFileToBuffer(filepath) {
const descriptor = fs.openSync(filepath, "r");
const { size } = fs.fstatSync(descriptor);
if (size <= 0) {
fs.closeSync(descriptor);
throw new Error("Empty file");
}
const bufferSize = Math.min(size, MaxBufferSize);
const buffer = Buffer.alloc(bufferSize);
fs.readSync(descriptor, buffer, 0, bufferSize, 0);
fs.closeSync(descriptor);
return buffer;
}
var image_size_default = imageSize;
function imageSize(input, callback) {
if (Buffer.isBuffer(input)) {
return lookup(input);
}
if (typeof input !== "string" || globalOptions.disabledFS) {
throw new TypeError("invalid invocation. input should be a Buffer");
}
const filepath = path.resolve(input);
if (typeof callback === "function") {
queue.push(
() => asyncFileToBuffer(filepath).then(
(buffer) => process.nextTick(callback, null, lookup(buffer, filepath))
).catch(callback)
);
} else {
const buffer = syncFileToBuffer(filepath);
return lookup(buffer, filepath);
}
}
const disableFS = (v) => {
globalOptions.disabledFS = v;
};
const disableTypes = (types2) => {
globalOptions.disabledTypes = types2;
};
const setConcurrency = (c) => {
queue.concurrency = c;
};
const types = Object.keys(typeHandlers);
export {
image_size_default as default,
disableFS,
disableTypes,
imageSize,
setConcurrency,
types
};

View file

@ -0,0 +1,4 @@
/// <reference types="node" />
type Bits = 16 | 32;
export declare function readUInt(buffer: Buffer, bits: Bits, offset: number, isBigEndian: boolean): number;
export {};

View file

@ -0,0 +1,9 @@
function readUInt(buffer, bits, offset, isBigEndian) {
offset = offset || 0;
const endian = isBigEndian ? "BE" : "LE";
const methodName = "readUInt" + bits + endian;
return buffer[methodName].call(buffer, offset);
}
export {
readUInt
};

View file

@ -0,0 +1,19 @@
export declare const typeHandlers: {
bmp: import("./types/interface.js").IImage;
cur: import("./types/interface.js").IImage;
dds: import("./types/interface.js").IImage;
gif: import("./types/interface.js").IImage;
icns: import("./types/interface.js").IImage;
ico: import("./types/interface.js").IImage;
j2c: import("./types/interface.js").IImage;
jp2: import("./types/interface.js").IImage;
jpg: import("./types/interface.js").IImage;
ktx: import("./types/interface.js").IImage;
png: import("./types/interface.js").IImage;
pnm: import("./types/interface.js").IImage;
psd: import("./types/interface.js").IImage;
svg: import("./types/interface.js").IImage;
tiff: import("./types/interface.js").IImage;
webp: import("./types/interface.js").IImage;
};
export type imageType = keyof typeof typeHandlers;

View file

@ -0,0 +1,37 @@
import { BMP } from "./types/bmp.js";
import { CUR } from "./types/cur.js";
import { DDS } from "./types/dds.js";
import { GIF } from "./types/gif.js";
import { ICNS } from "./types/icns.js";
import { ICO } from "./types/ico.js";
import { J2C } from "./types/j2c.js";
import { JP2 } from "./types/jp2.js";
import { JPG } from "./types/jpg.js";
import { KTX } from "./types/ktx.js";
import { PNG } from "./types/png.js";
import { PNM } from "./types/pnm.js";
import { PSD } from "./types/psd.js";
import { SVG } from "./types/svg.js";
import { TIFF } from "./types/tiff.js";
import { WEBP } from "./types/webp.js";
const typeHandlers = {
bmp: BMP,
cur: CUR,
dds: DDS,
gif: GIF,
icns: ICNS,
ico: ICO,
j2c: J2C,
jp2: JP2,
jpg: JPG,
ktx: KTX,
png: PNG,
pnm: PNM,
psd: PSD,
svg: SVG,
tiff: TIFF,
webp: WEBP
};
export {
typeHandlers
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const BMP: IImage;

View file

@ -0,0 +1,14 @@
const BMP = {
validate(buffer) {
return "BM" === buffer.toString("ascii", 0, 2);
},
calculate(buffer) {
return {
height: Math.abs(buffer.readInt32LE(22)),
width: buffer.readUInt32LE(18)
};
}
};
export {
BMP
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const CUR: IImage;

View file

@ -0,0 +1,16 @@
import { ICO } from "./ico.js";
const TYPE_CURSOR = 2;
const CUR = {
validate(buffer) {
if (buffer.readUInt16LE(0) !== 0) {
return false;
}
return buffer.readUInt16LE(2) === TYPE_CURSOR;
},
calculate(buffer) {
return ICO.calculate(buffer);
}
};
export {
CUR
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const DDS: IImage;

View file

@ -0,0 +1,14 @@
const DDS = {
validate(buffer) {
return buffer.readUInt32LE(0) === 542327876;
},
calculate(buffer) {
return {
height: buffer.readUInt32LE(12),
width: buffer.readUInt32LE(16)
};
}
};
export {
DDS
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const GIF: IImage;

View file

@ -0,0 +1,16 @@
const gifRegexp = /^GIF8[79]a/;
const GIF = {
validate(buffer) {
const signature = buffer.toString("ascii", 0, 6);
return gifRegexp.test(signature);
},
calculate(buffer) {
return {
height: buffer.readUInt16LE(8),
width: buffer.readUInt16LE(6)
};
}
};
export {
GIF
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const ICNS: IImage;

View file

@ -0,0 +1,87 @@
const SIZE_HEADER = 4 + 4;
const FILE_LENGTH_OFFSET = 4;
const ENTRY_LENGTH_OFFSET = 4;
const ICON_TYPE_SIZE = {
ICON: 32,
"ICN#": 32,
// m => 16 x 16
"icm#": 16,
icm4: 16,
icm8: 16,
// s => 16 x 16
"ics#": 16,
ics4: 16,
ics8: 16,
is32: 16,
s8mk: 16,
icp4: 16,
// l => 32 x 32
icl4: 32,
icl8: 32,
il32: 32,
l8mk: 32,
icp5: 32,
ic11: 32,
// h => 48 x 48
ich4: 48,
ich8: 48,
ih32: 48,
h8mk: 48,
// . => 64 x 64
icp6: 64,
ic12: 32,
// t => 128 x 128
it32: 128,
t8mk: 128,
ic07: 128,
// . => 256 x 256
ic08: 256,
ic13: 256,
// . => 512 x 512
ic09: 512,
ic14: 512,
// . => 1024 x 1024
ic10: 1024
};
function readImageHeader(buffer, imageOffset) {
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
return [
buffer.toString("ascii", imageOffset, imageLengthOffset),
buffer.readUInt32BE(imageLengthOffset)
];
}
function getImageSize(type) {
const size = ICON_TYPE_SIZE[type];
return { width: size, height: size, type };
}
const ICNS = {
validate(buffer) {
return "icns" === buffer.toString("ascii", 0, 4);
},
calculate(buffer) {
const bufferLength = buffer.length;
const fileLength = buffer.readUInt32BE(FILE_LENGTH_OFFSET);
let imageOffset = SIZE_HEADER;
let imageHeader = readImageHeader(buffer, imageOffset);
let imageSize = getImageSize(imageHeader[0]);
imageOffset += imageHeader[1];
if (imageOffset === fileLength) {
return imageSize;
}
const result = {
height: imageSize.height,
images: [imageSize],
width: imageSize.width
};
while (imageOffset < fileLength && imageOffset < bufferLength) {
imageHeader = readImageHeader(buffer, imageOffset);
imageSize = getImageSize(imageHeader[0]);
imageOffset += imageHeader[1];
result.images.push(imageSize);
}
return result;
}
};
export {
ICNS
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const ICO: IImage;

View file

@ -0,0 +1,42 @@
const TYPE_ICON = 1;
const SIZE_HEADER = 2 + 2 + 2;
const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4;
function getSizeFromOffset(buffer, offset) {
const value = buffer.readUInt8(offset);
return value === 0 ? 256 : value;
}
function getImageSize(buffer, imageIndex) {
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY;
return {
height: getSizeFromOffset(buffer, offset + 1),
width: getSizeFromOffset(buffer, offset)
};
}
const ICO = {
validate(buffer) {
if (buffer.readUInt16LE(0) !== 0) {
return false;
}
return buffer.readUInt16LE(2) === TYPE_ICON;
},
calculate(buffer) {
const nbImages = buffer.readUInt16LE(4);
const imageSize = getImageSize(buffer, 0);
if (nbImages === 1) {
return imageSize;
}
const imgs = [imageSize];
for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) {
imgs.push(getImageSize(buffer, imageIndex));
}
const result = {
height: imageSize.height,
images: imgs,
width: imageSize.width
};
return result;
}
};
export {
ICO
};

View file

@ -0,0 +1,14 @@
/// <reference types="node" />
export interface ISize {
width: number | undefined;
height: number | undefined;
orientation?: number;
type?: string;
}
export interface ISizeCalculationResult extends ISize {
images?: ISize[];
}
export interface IImage {
validate: (buffer: Buffer) => boolean;
calculate: (buffer: Buffer, filepath?: string) => ISizeCalculationResult;
}

View file

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const J2C: IImage;

View file

@ -0,0 +1,14 @@
const J2C = {
validate(buffer) {
return buffer.toString("hex", 0, 4) === "ff4fff51";
},
calculate(buffer) {
return {
height: buffer.readUInt32BE(12),
width: buffer.readUInt32BE(8)
};
}
};
export {
J2C
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const JP2: IImage;

View file

@ -0,0 +1,56 @@
const BoxTypes = {
ftyp: "66747970",
ihdr: "69686472",
jp2h: "6a703268",
jp__: "6a502020",
rreq: "72726571",
xml_: "786d6c20"
};
const calculateRREQLength = (box) => {
const unit = box.readUInt8(0);
let offset = 1 + 2 * unit;
const numStdFlags = box.readUInt16BE(offset);
const flagsLength = numStdFlags * (2 + unit);
offset = offset + 2 + flagsLength;
const numVendorFeatures = box.readUInt16BE(offset);
const featuresLength = numVendorFeatures * (16 + unit);
return offset + 2 + featuresLength;
};
const parseIHDR = (box) => {
return {
height: box.readUInt32BE(4),
width: box.readUInt32BE(8)
};
};
const JP2 = {
validate(buffer) {
const signature = buffer.toString("hex", 4, 8);
const signatureLength = buffer.readUInt32BE(0);
if (signature !== BoxTypes.jp__ || signatureLength < 1) {
return false;
}
const ftypeBoxStart = signatureLength + 4;
const ftypBoxLength = buffer.readUInt32BE(signatureLength);
const ftypBox = buffer.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength);
return ftypBox.toString("hex", 0, 4) === BoxTypes.ftyp;
},
calculate(buffer) {
const signatureLength = buffer.readUInt32BE(0);
const ftypBoxLength = buffer.readUInt16BE(signatureLength + 2);
let offset = signatureLength + 4 + ftypBoxLength;
const nextBoxType = buffer.toString("hex", offset, offset + 4);
switch (nextBoxType) {
case BoxTypes.rreq:
const MAGIC = 4;
offset = offset + 4 + MAGIC + calculateRREQLength(buffer.slice(offset + 4));
return parseIHDR(buffer.slice(offset + 8, offset + 24));
case BoxTypes.jp2h:
return parseIHDR(buffer.slice(offset + 8, offset + 24));
default:
throw new TypeError("Unsupported header found: " + buffer.toString("ascii", offset, offset + 4));
}
}
};
export {
JP2
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const JPG: IImage;

View file

@ -0,0 +1,95 @@
import { readUInt } from "../readUInt.js";
const EXIF_MARKER = "45786966";
const APP1_DATA_SIZE_BYTES = 2;
const EXIF_HEADER_BYTES = 6;
const TIFF_BYTE_ALIGN_BYTES = 2;
const BIG_ENDIAN_BYTE_ALIGN = "4d4d";
const LITTLE_ENDIAN_BYTE_ALIGN = "4949";
const IDF_ENTRY_BYTES = 12;
const NUM_DIRECTORY_ENTRIES_BYTES = 2;
function isEXIF(buffer) {
return buffer.toString("hex", 2, 6) === EXIF_MARKER;
}
function extractSize(buffer, index) {
return {
height: buffer.readUInt16BE(index),
width: buffer.readUInt16BE(index + 2)
};
}
function extractOrientation(exifBlock, isBigEndian) {
const idfOffset = 8;
const offset = EXIF_HEADER_BYTES + idfOffset;
const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian);
for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) {
const start = offset + NUM_DIRECTORY_ENTRIES_BYTES + directoryEntryNumber * IDF_ENTRY_BYTES;
const end = start + IDF_ENTRY_BYTES;
if (start > exifBlock.length) {
return;
}
const block = exifBlock.slice(start, end);
const tagNumber = readUInt(block, 16, 0, isBigEndian);
if (tagNumber === 274) {
const dataFormat = readUInt(block, 16, 2, isBigEndian);
if (dataFormat !== 3) {
return;
}
const numberOfComponents = readUInt(block, 32, 4, isBigEndian);
if (numberOfComponents !== 1) {
return;
}
return readUInt(block, 16, 8, isBigEndian);
}
}
}
function validateExifBlock(buffer, index) {
const exifBlock = buffer.slice(APP1_DATA_SIZE_BYTES, index);
const byteAlign = exifBlock.toString("hex", EXIF_HEADER_BYTES, EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES);
const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN;
const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN;
if (isBigEndian || isLittleEndian) {
return extractOrientation(exifBlock, isBigEndian);
}
}
function validateBuffer(buffer, index) {
if (index > buffer.length) {
throw new TypeError("Corrupt JPG, exceeded buffer limits");
}
if (buffer[index] !== 255) {
throw new TypeError("Invalid JPG, marker table corrupted");
}
}
const JPG = {
validate(buffer) {
const SOIMarker = buffer.toString("hex", 0, 2);
return "ffd8" === SOIMarker;
},
calculate(buffer) {
buffer = buffer.slice(4);
let orientation;
let next;
while (buffer.length) {
const i = buffer.readUInt16BE(0);
if (isEXIF(buffer)) {
orientation = validateExifBlock(buffer, i);
}
validateBuffer(buffer, i);
next = buffer[i + 1];
if (next === 192 || next === 193 || next === 194) {
const size = extractSize(buffer, i + 5);
if (!orientation) {
return size;
}
return {
height: size.height,
orientation,
width: size.width
};
}
buffer = buffer.slice(i + 2);
}
throw new TypeError("Invalid JPG, no size found");
}
};
export {
JPG
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const KTX: IImage;

View file

@ -0,0 +1,15 @@
const SIGNATURE = "KTX 11";
const KTX = {
validate(buffer) {
return SIGNATURE === buffer.toString("ascii", 1, 7);
},
calculate(buffer) {
return {
height: buffer.readUInt32LE(40),
width: buffer.readUInt32LE(36)
};
}
};
export {
KTX
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const PNG: IImage;

View file

@ -0,0 +1,33 @@
const pngSignature = "PNG\r\n\n";
const pngImageHeaderChunkName = "IHDR";
const pngFriedChunkName = "CgBI";
const PNG = {
validate(buffer) {
if (pngSignature === buffer.toString("ascii", 1, 8)) {
let chunkName = buffer.toString("ascii", 12, 16);
if (chunkName === pngFriedChunkName) {
chunkName = buffer.toString("ascii", 28, 32);
}
if (chunkName !== pngImageHeaderChunkName) {
throw new TypeError("Invalid PNG");
}
return true;
}
return false;
},
calculate(buffer) {
if (buffer.toString("ascii", 12, 16) === pngFriedChunkName) {
return {
height: buffer.readUInt32BE(36),
width: buffer.readUInt32BE(32)
};
}
return {
height: buffer.readUInt32BE(20),
width: buffer.readUInt32BE(16)
};
}
};
export {
PNG
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const PNM: IImage;

View file

@ -0,0 +1,72 @@
const PNMTypes = {
P1: "pbm/ascii",
P2: "pgm/ascii",
P3: "ppm/ascii",
P4: "pbm",
P5: "pgm",
P6: "ppm",
P7: "pam",
PF: "pfm"
};
const Signatures = Object.keys(PNMTypes);
const handlers = {
default: (lines) => {
let dimensions = [];
while (lines.length > 0) {
const line = lines.shift();
if (line[0] === "#") {
continue;
}
dimensions = line.split(" ");
break;
}
if (dimensions.length === 2) {
return {
height: parseInt(dimensions[1], 10),
width: parseInt(dimensions[0], 10)
};
} else {
throw new TypeError("Invalid PNM");
}
},
pam: (lines) => {
const size = {};
while (lines.length > 0) {
const line = lines.shift();
if (line.length > 16 || line.charCodeAt(0) > 128) {
continue;
}
const [key, value] = line.split(" ");
if (key && value) {
size[key.toLowerCase()] = parseInt(value, 10);
}
if (size.height && size.width) {
break;
}
}
if (size.height && size.width) {
return {
height: size.height,
width: size.width
};
} else {
throw new TypeError("Invalid PAM");
}
}
};
const PNM = {
validate(buffer) {
const signature = buffer.toString("ascii", 0, 2);
return Signatures.includes(signature);
},
calculate(buffer) {
const signature = buffer.toString("ascii", 0, 2);
const type = PNMTypes[signature];
const lines = buffer.toString("ascii", 3).split(/[\r\n]+/);
const handler = handlers[type] || handlers.default;
return handler(lines);
}
};
export {
PNM
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const PSD: IImage;

View file

@ -0,0 +1,14 @@
const PSD = {
validate(buffer) {
return "8BPS" === buffer.toString("ascii", 0, 4);
},
calculate(buffer) {
return {
height: buffer.readUInt32BE(14),
width: buffer.readUInt32BE(18)
};
}
};
export {
PSD
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const SVG: IImage;

View file

@ -0,0 +1,91 @@
const svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/;
const extractorRegExps = {
height: /\sheight=(['"])([^%]+?)\1/,
root: svgReg,
viewbox: /\sviewBox=(['"])(.+?)\1/i,
width: /\swidth=(['"])([^%]+?)\1/
};
const INCH_CM = 2.54;
const units = {
in: 96,
cm: 96 / INCH_CM,
em: 16,
ex: 8,
m: 96 / INCH_CM * 100,
mm: 96 / INCH_CM / 10,
pc: 96 / 72 / 12,
pt: 96 / 72,
px: 1
};
const unitsReg = new RegExp(`^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$`);
function parseLength(len) {
const m = unitsReg.exec(len);
if (!m) {
return void 0;
}
return Math.round(Number(m[1]) * (units[m[2]] || 1));
}
function parseViewbox(viewbox) {
const bounds = viewbox.split(" ");
return {
height: parseLength(bounds[3]),
width: parseLength(bounds[2])
};
}
function parseAttributes(root) {
const width = root.match(extractorRegExps.width);
const height = root.match(extractorRegExps.height);
const viewbox = root.match(extractorRegExps.viewbox);
return {
height: height && parseLength(height[2]),
viewbox: viewbox && parseViewbox(viewbox[2]),
width: width && parseLength(width[2])
};
}
function calculateByDimensions(attrs) {
return {
height: attrs.height,
width: attrs.width
};
}
function calculateByViewbox(attrs, viewbox) {
const ratio = viewbox.width / viewbox.height;
if (attrs.width) {
return {
height: Math.floor(attrs.width / ratio),
width: attrs.width
};
}
if (attrs.height) {
return {
height: attrs.height,
width: Math.floor(attrs.height * ratio)
};
}
return {
height: viewbox.height,
width: viewbox.width
};
}
const SVG = {
validate(buffer) {
const str = String(buffer);
return svgReg.test(str);
},
calculate(buffer) {
const root = buffer.toString("utf8").match(extractorRegExps.root);
if (root) {
const attrs = parseAttributes(root[0]);
if (attrs.width && attrs.height) {
return calculateByDimensions(attrs);
}
if (attrs.viewbox) {
return calculateByViewbox(attrs, attrs.viewbox);
}
}
throw new TypeError("Invalid SVG");
}
};
export {
SVG
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const TIFF: IImage;

View file

@ -0,0 +1,81 @@
import * as fs from "node:fs";
import { readUInt } from "../readUInt.js";
function readIFD(buffer, filepath, isBigEndian) {
const ifdOffset = readUInt(buffer, 32, 4, isBigEndian);
let bufferSize = 1024;
const fileSize = fs.statSync(filepath).size;
if (ifdOffset + bufferSize > fileSize) {
bufferSize = fileSize - ifdOffset - 10;
}
const endBuffer = Buffer.alloc(bufferSize);
const descriptor = fs.openSync(filepath, "r");
fs.readSync(descriptor, endBuffer, 0, bufferSize, ifdOffset);
fs.closeSync(descriptor);
return endBuffer.slice(2);
}
function readValue(buffer, isBigEndian) {
const low = readUInt(buffer, 16, 8, isBigEndian);
const high = readUInt(buffer, 16, 10, isBigEndian);
return (high << 16) + low;
}
function nextTag(buffer) {
if (buffer.length > 24) {
return buffer.slice(12);
}
}
function extractTags(buffer, isBigEndian) {
const tags = {};
let temp = buffer;
while (temp == null ? void 0 : temp.length) {
const code = readUInt(temp, 16, 0, isBigEndian);
const type = readUInt(temp, 16, 2, isBigEndian);
const length = readUInt(temp, 32, 4, isBigEndian);
if (code === 0) {
break;
} else {
if (length === 1 && (type === 3 || type === 4)) {
tags[code] = readValue(temp, isBigEndian);
}
temp = nextTag(temp);
}
}
return tags;
}
function determineEndianness(buffer) {
const signature = buffer.toString("ascii", 0, 2);
if ("II" === signature) {
return "LE";
} else if ("MM" === signature) {
return "BE";
}
}
const signatures = [
// '492049', // currently not supported
"49492a00",
// Little endian
"4d4d002a"
// Big Endian
// '4d4d002a', // BigTIFF > 4GB. currently not supported
];
const TIFF = {
validate(buffer) {
return signatures.includes(buffer.toString("hex", 0, 4));
},
calculate(buffer, filepath) {
if (!filepath) {
throw new TypeError("Tiff doesn't support buffer");
}
const isBigEndian = determineEndianness(buffer) === "BE";
const ifdBuffer = readIFD(buffer, filepath, isBigEndian);
const tags = extractTags(ifdBuffer, isBigEndian);
const width = tags[256];
const height = tags[257];
if (!width || !height) {
throw new TypeError("Invalid Tiff. Missing tags");
}
return { height, width };
}
};
export {
TIFF
};

View file

@ -0,0 +1,2 @@
import type { IImage } from './interface';
export declare const WEBP: IImage;

View file

@ -0,0 +1,51 @@
function calculateExtended(buffer) {
return {
height: 1 + buffer.readUIntLE(7, 3),
width: 1 + buffer.readUIntLE(4, 3)
};
}
function calculateLossless(buffer) {
return {
height: 1 + ((buffer[4] & 15) << 10 | buffer[3] << 2 | (buffer[2] & 192) >> 6),
width: 1 + ((buffer[2] & 63) << 8 | buffer[1])
};
}
function calculateLossy(buffer) {
return {
height: buffer.readInt16LE(8) & 16383,
width: buffer.readInt16LE(6) & 16383
};
}
const WEBP = {
validate(buffer) {
const riffHeader = "RIFF" === buffer.toString("ascii", 0, 4);
const webpHeader = "WEBP" === buffer.toString("ascii", 8, 12);
const vp8Header = "VP8" === buffer.toString("ascii", 12, 15);
return riffHeader && webpHeader && vp8Header;
},
calculate(buffer) {
const chunkHeader = buffer.toString("ascii", 12, 16);
buffer = buffer.slice(20, 30);
if (chunkHeader === "VP8X") {
const extendedHeader = buffer[0];
const validStart = (extendedHeader & 192) === 0;
const validEnd = (extendedHeader & 1) === 0;
if (validStart && validEnd) {
return calculateExtended(buffer);
} else {
throw new TypeError("Invalid WebP");
}
}
if (chunkHeader === "VP8 " && buffer[0] !== 47) {
return calculateLossy(buffer);
}
const signature = buffer.toString("hex", 3, 6);
if (chunkHeader === "VP8L" && signature !== "9d012a") {
return calculateLossless(buffer);
}
throw new TypeError("Invalid WebP");
}
};
export {
WEBP
};

39
node_modules/astro/dist/assets/vendor/queue/queue.d.ts generated vendored Normal file
View file

@ -0,0 +1,39 @@
/**
* Since CustomEvent is only supported in nodejs since version 19,
* you have to create your own class instead of using CustomEvent
* @see https://github.com/nodejs/node/issues/40678
* */
export class QueueEvent extends Event {
constructor(name: any, detail: any);
detail: any;
}
export default class Queue extends EventTarget {
constructor(options?: {});
concurrency: any;
timeout: any;
autostart: any;
results: any;
pending: number;
session: number;
running: boolean;
jobs: any[];
timers: any[];
_errorHandler(evt: any): void;
pop(): any;
shift(): any;
indexOf(searchElement: any, fromIndex: any): number;
lastIndexOf(searchElement: any, fromIndex: any): number;
slice(start: any, end: any): Queue;
reverse(): Queue;
push(...workers: any[]): number;
unshift(...workers: any[]): number;
splice(start: any, deleteCount: any, ...workers: any[]): Queue;
get length(): number;
start(callback: any): any;
stop(): void;
end(error: any): void;
clearTimers(): void;
_addCallbackToEndEvent(cb: any): void;
_createPromiseToEndEvent(): Promise<any>;
done(error: any): void;
}

187
node_modules/astro/dist/assets/vendor/queue/queue.js generated vendored Normal file
View file

@ -0,0 +1,187 @@
const has = Object.prototype.hasOwnProperty;
class QueueEvent extends Event {
constructor(name, detail) {
super(name);
this.detail = detail;
}
}
class Queue extends EventTarget {
constructor(options = {}) {
super();
const { concurrency = Infinity, timeout = 0, autostart = false, results = null } = options;
this.concurrency = concurrency;
this.timeout = timeout;
this.autostart = autostart;
this.results = results;
this.pending = 0;
this.session = 0;
this.running = false;
this.jobs = [];
this.timers = [];
this.addEventListener("error", this._errorHandler);
}
_errorHandler(evt) {
this.end(evt.detail.error);
}
pop() {
return this.jobs.pop();
}
shift() {
return this.jobs.shift();
}
indexOf(searchElement, fromIndex) {
return this.jobs.indexOf(searchElement, fromIndex);
}
lastIndexOf(searchElement, fromIndex) {
if (fromIndex !== void 0) {
return this.jobs.lastIndexOf(searchElement, fromIndex);
}
return this.jobs.lastIndexOf(searchElement);
}
slice(start, end) {
this.jobs = this.jobs.slice(start, end);
return this;
}
reverse() {
this.jobs.reverse();
return this;
}
push(...workers) {
const methodResult = this.jobs.push(...workers);
if (this.autostart) {
this.start();
}
return methodResult;
}
unshift(...workers) {
const methodResult = this.jobs.unshift(...workers);
if (this.autostart) {
this.start();
}
return methodResult;
}
splice(start, deleteCount, ...workers) {
this.jobs.splice(start, deleteCount, ...workers);
if (this.autostart) {
this.start();
}
return this;
}
get length() {
return this.pending + this.jobs.length;
}
start(callback) {
let awaiter;
if (callback) {
this._addCallbackToEndEvent(callback);
} else {
awaiter = this._createPromiseToEndEvent();
}
this.running = true;
if (this.pending >= this.concurrency) {
return;
}
if (this.jobs.length === 0) {
if (this.pending === 0) {
this.done();
}
return;
}
const job = this.jobs.shift();
const session = this.session;
const timeout = job !== void 0 && has.call(job, "timeout") ? job.timeout : this.timeout;
let once = true;
let timeoutId = null;
let didTimeout = false;
let resultIndex = null;
const next = (error, ...result) => {
if (once && this.session === session) {
once = false;
this.pending--;
if (timeoutId !== null) {
this.timers = this.timers.filter((tID) => tID !== timeoutId);
clearTimeout(timeoutId);
}
if (error) {
this.dispatchEvent(new QueueEvent("error", { error, job }));
} else if (!didTimeout) {
if (resultIndex !== null && this.results !== null) {
this.results[resultIndex] = [...result];
}
this.dispatchEvent(new QueueEvent("success", { result: [...result], job }));
}
if (this.session === session) {
if (this.pending === 0 && this.jobs.length === 0) {
this.done();
} else if (this.running) {
this.start();
}
}
}
};
if (timeout) {
timeoutId = setTimeout(() => {
didTimeout = true;
this.dispatchEvent(new QueueEvent("timeout", { next, job }));
next();
}, timeout);
this.timers.push(timeoutId);
}
if (this.results != null) {
resultIndex = this.results.length;
this.results[resultIndex] = null;
}
this.pending++;
this.dispatchEvent(new QueueEvent("start", { job }));
const promise = job(next);
if (promise !== void 0 && typeof promise.then === "function") {
promise.then(function(result) {
return next(void 0, result);
}).catch(function(err) {
return next(err || true);
});
}
if (this.running && this.jobs.length > 0) {
return this.start();
}
return awaiter;
}
stop() {
this.running = false;
}
end(error) {
this.clearTimers();
this.jobs.length = 0;
this.pending = 0;
this.done(error);
}
clearTimers() {
this.timers.forEach((timer) => {
clearTimeout(timer);
});
this.timers = [];
}
_addCallbackToEndEvent(cb) {
const onend = (evt) => {
this.removeEventListener("end", onend);
cb(evt.detail.error, this.results);
};
this.addEventListener("end", onend);
}
_createPromiseToEndEvent() {
return new Promise((resolve) => {
this._addCallbackToEndEvent((error, results) => {
resolve({ error, results });
});
});
}
done(error) {
this.session++;
this.running = false;
this.dispatchEvent(new QueueEvent("end", { error }));
}
}
export {
QueueEvent,
Queue as default
};