astro 5.16.6 → 5.16.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Code.astro +2 -2
- package/components/Image.astro +2 -2
- package/components/Picture.astro +1 -1
- package/dist/assets/build/remote.js +1 -1
- package/dist/assets/endpoint/dev.js +44 -16
- package/dist/assets/fonts/config.d.ts +3 -0
- package/dist/assets/fonts/config.js +3 -2
- package/dist/assets/fonts/constants.js +2 -1
- package/dist/assets/fonts/core/resolve-families.js +1 -0
- package/dist/assets/fonts/definitions.d.ts +10 -2
- package/dist/assets/fonts/infra/remote-font-provider-resolver.d.ts +2 -2
- package/dist/assets/fonts/infra/unifont-font-resolver.d.ts +24 -0
- package/dist/assets/fonts/infra/unifont-font-resolver.js +59 -0
- package/dist/assets/fonts/orchestrate.d.ts +6 -4
- package/dist/assets/fonts/orchestrate.js +16 -32
- package/dist/assets/fonts/providers/entrypoints/bunny.d.ts +1 -1
- package/dist/assets/fonts/providers/entrypoints/fontshare.d.ts +1 -1
- package/dist/assets/fonts/providers/entrypoints/fontsource.d.ts +1 -1
- package/dist/assets/fonts/providers/index.d.ts +6 -8
- package/dist/assets/fonts/providers/index.js +10 -14
- package/dist/assets/fonts/types.d.ts +17 -4
- package/dist/assets/fonts/vite-plugin-fonts.js +6 -1
- package/dist/assets/utils/index.d.ts +1 -1
- package/dist/assets/utils/index.js +8 -8
- package/dist/assets/utils/vendor/image-size/detector.d.ts +1 -1
- package/dist/assets/utils/vendor/image-size/detector.js +2 -1
- package/dist/assets/utils/vendor/image-size/types/bmp.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/gif.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/heif.js +51 -29
- package/dist/assets/utils/vendor/image-size/types/icns.js +13 -14
- package/dist/assets/utils/vendor/image-size/types/ico.js +5 -5
- package/dist/assets/utils/vendor/image-size/types/index.d.ts +3 -3
- package/dist/assets/utils/vendor/image-size/types/index.js +4 -0
- package/dist/assets/utils/vendor/image-size/types/interface.d.ts +6 -6
- package/dist/assets/utils/vendor/image-size/types/j2c.js +2 -2
- package/dist/assets/utils/vendor/image-size/types/jp2.js +5 -3
- package/dist/assets/utils/vendor/image-size/types/jpg.js +4 -4
- package/dist/assets/utils/vendor/image-size/types/jxl-stream.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jxl-stream.js +36 -0
- package/dist/assets/utils/vendor/image-size/types/jxl.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jxl.js +57 -0
- package/dist/assets/utils/vendor/image-size/types/ktx.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/png.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/pnm.js +5 -7
- package/dist/assets/utils/vendor/image-size/types/psd.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/tiff.js +93 -40
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +3 -2
- package/dist/assets/utils/vendor/image-size/types/utils.js +24 -22
- package/dist/assets/utils/vendor/image-size/types/webp.js +5 -6
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.d.ts +10 -0
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.js +41 -0
- package/dist/assets/vite-plugin-assets.js +7 -0
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/config/entrypoint.d.ts +1 -2
- package/dist/config/entrypoint.js +1 -2
- package/dist/content/content-layer.js +3 -3
- package/dist/content/utils.js +9 -2
- package/dist/core/app/index.d.ts +1 -1
- package/dist/core/app/index.js +1 -1
- package/dist/core/config/schemas/base.d.ts +7 -0
- package/dist/core/config/schemas/relative.d.ts +9 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/routing/manifest/create.js +9 -6
- package/dist/runtime/client/dev-toolbar/apps/audit/rules/perf.js +1 -0
- package/dist/runtime/server/render/astro/render.js +26 -3
- package/dist/runtime/server/render/common.d.ts +1 -0
- package/dist/runtime/server/render/common.js +8 -0
- package/dist/transitions/router.js +2 -0
- package/dist/types/public/config.d.ts +2 -2
- package/dist/types/public/context.d.ts +303 -284
- package/dist/vite-plugin-astro-server/base.js +3 -2
- package/dist/vite-plugin-astro-server/request.js +3 -0
- package/dist/vite-plugin-astro-server/response.js +4 -6
- package/package.json +14 -14
- package/dist/assets/fonts/core/dedupe-font-faces.d.ts +0 -2
- package/dist/assets/fonts/core/dedupe-font-faces.js +0 -30
- package/dist/assets/fonts/core/extract-unifont-providers.d.ts +0 -10
- package/dist/assets/fonts/core/extract-unifont-providers.js +0 -28
- package/dist/assets/utils/remotePattern.d.ts +0 -1
- package/dist/assets/utils/remotePattern.js +0 -16
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { imageType } from './types/index.
|
|
1
|
+
import type { imageType } from './types/index.ts';
|
|
2
2
|
export declare function detector(input: Uint8Array): imageType | undefined;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { typeHandlers, types } from "./types/index.js";
|
|
2
2
|
const firstBytes = /* @__PURE__ */ new Map([
|
|
3
|
+
[0, "heif"],
|
|
3
4
|
[56, "psd"],
|
|
4
5
|
[66, "bmp"],
|
|
5
6
|
[68, "dds"],
|
|
@@ -17,7 +18,7 @@ function detector(input) {
|
|
|
17
18
|
if (type && typeHandlers.get(type).validate(input)) {
|
|
18
19
|
return type;
|
|
19
20
|
}
|
|
20
|
-
return types.find((
|
|
21
|
+
return types.find((imageType) => typeHandlers.get(imageType).validate(input));
|
|
21
22
|
}
|
|
22
23
|
export {
|
|
23
24
|
detector
|
|
@@ -13,41 +13,63 @@ const brandMap = {
|
|
|
13
13
|
hevx: "heic"
|
|
14
14
|
// heic-sequence
|
|
15
15
|
};
|
|
16
|
-
function
|
|
17
|
-
let
|
|
16
|
+
function detectType(input, start, end) {
|
|
17
|
+
let hasAvif = false;
|
|
18
|
+
let hasHeic = false;
|
|
19
|
+
let hasHeif = false;
|
|
18
20
|
for (let i = start; i <= end; i += 4) {
|
|
19
|
-
const brand = toUTF8String(
|
|
20
|
-
if (brand
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
if ("avif" in brandsDetected || "avis" in brandsDetected) {
|
|
25
|
-
return "avif";
|
|
26
|
-
} else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) {
|
|
27
|
-
return "heic";
|
|
28
|
-
} else if ("mif1" in brandsDetected || "msf1" in brandsDetected) {
|
|
29
|
-
return "heif";
|
|
21
|
+
const brand = toUTF8String(input, i, i + 4);
|
|
22
|
+
if (brand === "avif" || brand === "avis") hasAvif = true;
|
|
23
|
+
else if (brand === "heic" || brand === "heix" || brand === "hevc" || brand === "hevx") hasHeic = true;
|
|
24
|
+
else if (brand === "mif1" || brand === "msf1") hasHeif = true;
|
|
30
25
|
}
|
|
26
|
+
if (hasAvif) return "avif";
|
|
27
|
+
if (hasHeic) return "heic";
|
|
28
|
+
if (hasHeif) return "heif";
|
|
31
29
|
}
|
|
32
30
|
const HEIF = {
|
|
33
|
-
validate(
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
validate(input) {
|
|
32
|
+
const boxType = toUTF8String(input, 4, 8);
|
|
33
|
+
if (boxType !== "ftyp") return false;
|
|
34
|
+
const ftypBox = findBox(input, "ftyp", 0);
|
|
35
|
+
if (!ftypBox) return false;
|
|
36
|
+
const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12);
|
|
37
|
+
return brand in brandMap;
|
|
37
38
|
},
|
|
38
|
-
calculate(
|
|
39
|
-
const metaBox = findBox(
|
|
40
|
-
const iprpBox = metaBox && findBox(
|
|
41
|
-
const ipcoBox = iprpBox && findBox(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
calculate(input) {
|
|
40
|
+
const metaBox = findBox(input, "meta", 0);
|
|
41
|
+
const iprpBox = metaBox && findBox(input, "iprp", metaBox.offset + 12);
|
|
42
|
+
const ipcoBox = iprpBox && findBox(input, "ipco", iprpBox.offset + 8);
|
|
43
|
+
if (!ipcoBox) {
|
|
44
|
+
throw new TypeError("Invalid HEIF, no ipco box found");
|
|
45
|
+
}
|
|
46
|
+
const type = detectType(input, 8, metaBox.offset);
|
|
47
|
+
const images = [];
|
|
48
|
+
let currentOffset = ipcoBox.offset + 8;
|
|
49
|
+
while (currentOffset < ipcoBox.offset + ipcoBox.size) {
|
|
50
|
+
const ispeBox = findBox(input, "ispe", currentOffset);
|
|
51
|
+
if (!ispeBox) break;
|
|
52
|
+
const rawWidth = readUInt32BE(input, ispeBox.offset + 12);
|
|
53
|
+
const rawHeight = readUInt32BE(input, ispeBox.offset + 16);
|
|
54
|
+
const clapBox = findBox(input, "clap", currentOffset);
|
|
55
|
+
let width = rawWidth;
|
|
56
|
+
let height = rawHeight;
|
|
57
|
+
if (clapBox && clapBox.offset < ipcoBox.offset + ipcoBox.size) {
|
|
58
|
+
const cropRight = readUInt32BE(input, clapBox.offset + 12);
|
|
59
|
+
width = rawWidth - cropRight;
|
|
60
|
+
}
|
|
61
|
+
images.push({ height, width });
|
|
62
|
+
currentOffset = ispeBox.offset + ispeBox.size;
|
|
63
|
+
}
|
|
64
|
+
if (images.length === 0) {
|
|
65
|
+
throw new TypeError("Invalid HEIF, no sizes found");
|
|
49
66
|
}
|
|
50
|
-
|
|
67
|
+
return {
|
|
68
|
+
width: images[0].width,
|
|
69
|
+
height: images[0].height,
|
|
70
|
+
type,
|
|
71
|
+
...images.length > 1 ? { images } : {}
|
|
72
|
+
};
|
|
51
73
|
}
|
|
52
74
|
};
|
|
53
75
|
export {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readUInt32BE, toUTF8String } from "./utils.js";
|
|
2
2
|
const SIZE_HEADER = 4 + 4;
|
|
3
3
|
const FILE_LENGTH_OFFSET = 4;
|
|
4
4
|
const ENTRY_LENGTH_OFFSET = 4;
|
|
@@ -61,22 +61,21 @@ const ICNS = {
|
|
|
61
61
|
const inputLength = input.length;
|
|
62
62
|
const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET);
|
|
63
63
|
let imageOffset = SIZE_HEADER;
|
|
64
|
-
|
|
65
|
-
let imageSize = getImageSize(imageHeader[0]);
|
|
66
|
-
imageOffset += imageHeader[1];
|
|
67
|
-
if (imageOffset === fileLength) return imageSize;
|
|
68
|
-
const result = {
|
|
69
|
-
height: imageSize.height,
|
|
70
|
-
images: [imageSize],
|
|
71
|
-
width: imageSize.width
|
|
72
|
-
};
|
|
64
|
+
const images = [];
|
|
73
65
|
while (imageOffset < fileLength && imageOffset < inputLength) {
|
|
74
|
-
imageHeader = readImageHeader(input, imageOffset);
|
|
75
|
-
imageSize = getImageSize(imageHeader[0]);
|
|
66
|
+
const imageHeader = readImageHeader(input, imageOffset);
|
|
67
|
+
const imageSize = getImageSize(imageHeader[0]);
|
|
68
|
+
images.push(imageSize);
|
|
76
69
|
imageOffset += imageHeader[1];
|
|
77
|
-
result.images.push(imageSize);
|
|
78
70
|
}
|
|
79
|
-
|
|
71
|
+
if (images.length === 0) {
|
|
72
|
+
throw new TypeError("Invalid ICNS, no sizes found");
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
width: images[0].width,
|
|
76
|
+
height: images[0].height,
|
|
77
|
+
...images.length > 1 ? { images } : {}
|
|
78
|
+
};
|
|
80
79
|
}
|
|
81
80
|
};
|
|
82
81
|
export {
|
|
@@ -25,14 +25,14 @@ const ICO = {
|
|
|
25
25
|
const nbImages = readUInt16LE(input, 4);
|
|
26
26
|
const imageSize = getImageSize(input, 0);
|
|
27
27
|
if (nbImages === 1) return imageSize;
|
|
28
|
-
const
|
|
29
|
-
for (let imageIndex =
|
|
30
|
-
|
|
28
|
+
const images = [];
|
|
29
|
+
for (let imageIndex = 0; imageIndex < nbImages; imageIndex += 1) {
|
|
30
|
+
images.push(getImageSize(input, imageIndex));
|
|
31
31
|
}
|
|
32
32
|
return {
|
|
33
|
+
width: imageSize.width,
|
|
33
34
|
height: imageSize.height,
|
|
34
|
-
images
|
|
35
|
-
width: imageSize.width
|
|
35
|
+
images
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const typeHandlers: Map<"jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga", import("./interface.js").IImage>;
|
|
2
|
-
export declare const types: ("jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga")[];
|
|
3
|
-
export type imageType = typeof types[number];
|
|
1
|
+
export declare const typeHandlers: Map<"jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "jxl" | "jxl-stream" | "pnm" | "psd" | "tga", import("./interface.js").IImage>;
|
|
2
|
+
export declare const types: ("jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "jxl" | "jxl-stream" | "pnm" | "psd" | "tga")[];
|
|
3
|
+
export type imageType = (typeof types)[number];
|
|
@@ -8,6 +8,8 @@ import { ICO } from "./ico.js";
|
|
|
8
8
|
import { J2C } from "./j2c.js";
|
|
9
9
|
import { JP2 } from "./jp2.js";
|
|
10
10
|
import { JPG } from "./jpg.js";
|
|
11
|
+
import { JXL } from "./jxl.js";
|
|
12
|
+
import { JXLStream } from "./jxl-stream.js";
|
|
11
13
|
import { KTX } from "./ktx.js";
|
|
12
14
|
import { PNG } from "./png.js";
|
|
13
15
|
import { PNM } from "./pnm.js";
|
|
@@ -27,6 +29,8 @@ const typeHandlers = /* @__PURE__ */ new Map([
|
|
|
27
29
|
["j2c", J2C],
|
|
28
30
|
["jp2", JP2],
|
|
29
31
|
["jpg", JPG],
|
|
32
|
+
["jxl", JXL],
|
|
33
|
+
["jxl-stream", JXLStream],
|
|
30
34
|
["ktx", KTX],
|
|
31
35
|
["png", PNG],
|
|
32
36
|
["pnm", PNM],
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export
|
|
2
|
-
width: number
|
|
3
|
-
height: number
|
|
1
|
+
export interface ISize {
|
|
2
|
+
width: number;
|
|
3
|
+
height: number;
|
|
4
4
|
orientation?: number;
|
|
5
5
|
type?: string;
|
|
6
|
-
}
|
|
6
|
+
}
|
|
7
7
|
export type ISizeCalculationResult = {
|
|
8
8
|
images?: ISize[];
|
|
9
9
|
} & ISize;
|
|
10
|
-
export
|
|
10
|
+
export interface IImage {
|
|
11
11
|
validate: (input: Uint8Array) => boolean;
|
|
12
12
|
calculate: (input: Uint8Array) => ISizeCalculationResult;
|
|
13
|
-
}
|
|
13
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readUInt32BE } from "./utils.js";
|
|
2
2
|
const J2C = {
|
|
3
3
|
// TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC
|
|
4
|
-
validate: (input) =>
|
|
4
|
+
validate: (input) => readUInt32BE(input, 0) === 4283432785,
|
|
5
5
|
calculate: (input) => ({
|
|
6
6
|
height: readUInt32BE(input, 12),
|
|
7
7
|
width: readUInt32BE(input, 8)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { readUInt32BE,
|
|
1
|
+
import { findBox, readUInt32BE, toUTF8String } from "./utils.js";
|
|
2
2
|
const JP2 = {
|
|
3
3
|
validate(input) {
|
|
4
|
-
|
|
4
|
+
const boxType = toUTF8String(input, 4, 8);
|
|
5
|
+
if (boxType !== "jP ") return false;
|
|
5
6
|
const ftypBox = findBox(input, "ftyp", 0);
|
|
6
7
|
if (!ftypBox) return false;
|
|
7
|
-
|
|
8
|
+
const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12);
|
|
9
|
+
return brand === "jp2 ";
|
|
8
10
|
},
|
|
9
11
|
calculate(input) {
|
|
10
12
|
const jp2hBox = findBox(input, "jp2h", 0);
|
|
@@ -61,20 +61,20 @@ function validateInput(input, index) {
|
|
|
61
61
|
}
|
|
62
62
|
const JPG = {
|
|
63
63
|
validate: (input) => toHexString(input, 0, 2) === "ffd8",
|
|
64
|
-
calculate(
|
|
65
|
-
input =
|
|
64
|
+
calculate(_input) {
|
|
65
|
+
let input = _input.slice(4);
|
|
66
66
|
let orientation;
|
|
67
67
|
let next;
|
|
68
68
|
while (input.length) {
|
|
69
69
|
const i = readUInt16BE(input, 0);
|
|
70
|
+
validateInput(input, i);
|
|
70
71
|
if (input[i] !== 255) {
|
|
71
|
-
input = input.slice(
|
|
72
|
+
input = input.slice(1);
|
|
72
73
|
continue;
|
|
73
74
|
}
|
|
74
75
|
if (isEXIF(input)) {
|
|
75
76
|
orientation = validateExifBlock(input, i);
|
|
76
77
|
}
|
|
77
|
-
validateInput(input, i);
|
|
78
78
|
next = input[i + 1];
|
|
79
79
|
if (next === 192 || next === 193 || next === 194) {
|
|
80
80
|
const size = extractSize(input, i + 5);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BitReader } from "../utils/bit-reader.js";
|
|
2
|
+
import { toHexString } from "./utils.js";
|
|
3
|
+
function calculateImageDimension(reader, isSmallImage) {
|
|
4
|
+
if (isSmallImage) {
|
|
5
|
+
return 8 * (1 + reader.getBits(5));
|
|
6
|
+
}
|
|
7
|
+
const sizeClass = reader.getBits(2);
|
|
8
|
+
const extraBits = [9, 13, 18, 30][sizeClass];
|
|
9
|
+
return 1 + reader.getBits(extraBits);
|
|
10
|
+
}
|
|
11
|
+
function calculateImageWidth(reader, isSmallImage, widthMode, height) {
|
|
12
|
+
if (isSmallImage && widthMode === 0) {
|
|
13
|
+
return 8 * (1 + reader.getBits(5));
|
|
14
|
+
}
|
|
15
|
+
if (widthMode === 0) {
|
|
16
|
+
return calculateImageDimension(reader, false);
|
|
17
|
+
}
|
|
18
|
+
const aspectRatios = [1, 1.2, 4 / 3, 1.5, 16 / 9, 5 / 4, 2];
|
|
19
|
+
return Math.floor(height * aspectRatios[widthMode - 1]);
|
|
20
|
+
}
|
|
21
|
+
const JXLStream = {
|
|
22
|
+
validate: (input) => {
|
|
23
|
+
return toHexString(input, 0, 2) === "ff0a";
|
|
24
|
+
},
|
|
25
|
+
calculate(input) {
|
|
26
|
+
const reader = new BitReader(input, "little-endian");
|
|
27
|
+
const isSmallImage = reader.getBits(1) === 1;
|
|
28
|
+
const height = calculateImageDimension(reader, isSmallImage);
|
|
29
|
+
const widthMode = reader.getBits(3);
|
|
30
|
+
const width = calculateImageWidth(reader, isSmallImage, widthMode, height);
|
|
31
|
+
return { width, height };
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
JXLStream
|
|
36
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { JXLStream } from "./jxl-stream.js";
|
|
2
|
+
import { findBox, toUTF8String } from "./utils.js";
|
|
3
|
+
function extractCodestream(input) {
|
|
4
|
+
const jxlcBox = findBox(input, "jxlc", 0);
|
|
5
|
+
if (jxlcBox) {
|
|
6
|
+
return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size);
|
|
7
|
+
}
|
|
8
|
+
const partialStreams = extractPartialStreams(input);
|
|
9
|
+
if (partialStreams.length > 0) {
|
|
10
|
+
return concatenateCodestreams(partialStreams);
|
|
11
|
+
}
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
function extractPartialStreams(input) {
|
|
15
|
+
const partialStreams = [];
|
|
16
|
+
let offset = 0;
|
|
17
|
+
while (offset < input.length) {
|
|
18
|
+
const jxlpBox = findBox(input, "jxlp", offset);
|
|
19
|
+
if (!jxlpBox) break;
|
|
20
|
+
partialStreams.push(
|
|
21
|
+
input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size)
|
|
22
|
+
);
|
|
23
|
+
offset = jxlpBox.offset + jxlpBox.size;
|
|
24
|
+
}
|
|
25
|
+
return partialStreams;
|
|
26
|
+
}
|
|
27
|
+
function concatenateCodestreams(partialCodestreams) {
|
|
28
|
+
const totalLength = partialCodestreams.reduce(
|
|
29
|
+
(acc, curr) => acc + curr.length,
|
|
30
|
+
0
|
|
31
|
+
);
|
|
32
|
+
const codestream = new Uint8Array(totalLength);
|
|
33
|
+
let position = 0;
|
|
34
|
+
for (const partial of partialCodestreams) {
|
|
35
|
+
codestream.set(partial, position);
|
|
36
|
+
position += partial.length;
|
|
37
|
+
}
|
|
38
|
+
return codestream;
|
|
39
|
+
}
|
|
40
|
+
const JXL = {
|
|
41
|
+
validate: (input) => {
|
|
42
|
+
const boxType = toUTF8String(input, 4, 8);
|
|
43
|
+
if (boxType !== "JXL ") return false;
|
|
44
|
+
const ftypBox = findBox(input, "ftyp", 0);
|
|
45
|
+
if (!ftypBox) return false;
|
|
46
|
+
const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12);
|
|
47
|
+
return brand === "jxl ";
|
|
48
|
+
},
|
|
49
|
+
calculate(input) {
|
|
50
|
+
const codestream = extractCodestream(input);
|
|
51
|
+
if (codestream) return JXLStream.calculate(codestream);
|
|
52
|
+
throw new Error("No codestream found in JXL container");
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
JXL
|
|
57
|
+
};
|
|
@@ -22,12 +22,11 @@ const handlers = {
|
|
|
22
22
|
}
|
|
23
23
|
if (dimensions.length === 2) {
|
|
24
24
|
return {
|
|
25
|
-
height: parseInt(dimensions[1], 10),
|
|
26
|
-
width: parseInt(dimensions[0], 10)
|
|
25
|
+
height: Number.parseInt(dimensions[1], 10),
|
|
26
|
+
width: Number.parseInt(dimensions[0], 10)
|
|
27
27
|
};
|
|
28
|
-
} else {
|
|
29
|
-
throw new TypeError("Invalid PNM");
|
|
30
28
|
}
|
|
29
|
+
throw new TypeError("Invalid PNM");
|
|
31
30
|
},
|
|
32
31
|
pam: (lines) => {
|
|
33
32
|
const size = {};
|
|
@@ -38,7 +37,7 @@ const handlers = {
|
|
|
38
37
|
}
|
|
39
38
|
const [key, value] = line.split(" ");
|
|
40
39
|
if (key && value) {
|
|
41
|
-
size[key.toLowerCase()] = parseInt(value, 10);
|
|
40
|
+
size[key.toLowerCase()] = Number.parseInt(value, 10);
|
|
42
41
|
}
|
|
43
42
|
if (size.height && size.width) {
|
|
44
43
|
break;
|
|
@@ -49,9 +48,8 @@ const handlers = {
|
|
|
49
48
|
height: size.height,
|
|
50
49
|
width: size.width
|
|
51
50
|
};
|
|
52
|
-
} else {
|
|
53
|
-
throw new TypeError("Invalid PAM");
|
|
54
51
|
}
|
|
52
|
+
throw new TypeError("Invalid PAM");
|
|
55
53
|
}
|
|
56
54
|
};
|
|
57
55
|
const PNM = {
|
|
@@ -1,64 +1,117 @@
|
|
|
1
|
-
import { readUInt, toHexString, toUTF8String } from "./utils.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { readUInt, readUInt64, toHexString, toUTF8String } from "./utils.js";
|
|
2
|
+
const CONSTANTS = {
|
|
3
|
+
TAG: {
|
|
4
|
+
WIDTH: 256,
|
|
5
|
+
HEIGHT: 257,
|
|
6
|
+
COMPRESSION: 259
|
|
7
|
+
},
|
|
8
|
+
TYPE: {
|
|
9
|
+
SHORT: 3,
|
|
10
|
+
LONG: 4,
|
|
11
|
+
LONG8: 16
|
|
12
|
+
},
|
|
13
|
+
ENTRY_SIZE: {
|
|
14
|
+
STANDARD: 12,
|
|
15
|
+
BIG: 20
|
|
16
|
+
},
|
|
17
|
+
COUNT_SIZE: {
|
|
18
|
+
STANDARD: 2,
|
|
19
|
+
BIG: 8
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function readIFD(input, { isBigEndian, isBigTiff }) {
|
|
23
|
+
const ifdOffset = isBigTiff ? Number(readUInt64(input, 8, isBigEndian)) : readUInt(input, 32, 4, isBigEndian);
|
|
24
|
+
const entryCountSize = isBigTiff ? CONSTANTS.COUNT_SIZE.BIG : CONSTANTS.COUNT_SIZE.STANDARD;
|
|
25
|
+
return input.slice(ifdOffset + entryCountSize);
|
|
5
26
|
}
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
27
|
+
function readTagValue(input, type, offset, isBigEndian) {
|
|
28
|
+
switch (type) {
|
|
29
|
+
case CONSTANTS.TYPE.SHORT:
|
|
30
|
+
return readUInt(input, 16, offset, isBigEndian);
|
|
31
|
+
case CONSTANTS.TYPE.LONG:
|
|
32
|
+
return readUInt(input, 32, offset, isBigEndian);
|
|
33
|
+
case CONSTANTS.TYPE.LONG8: {
|
|
34
|
+
const value = Number(readUInt64(input, offset, isBigEndian));
|
|
35
|
+
if (value > Number.MAX_SAFE_INTEGER) {
|
|
36
|
+
throw new TypeError("Value too large");
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
default:
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
10
43
|
}
|
|
11
|
-
function nextTag(input) {
|
|
12
|
-
|
|
13
|
-
|
|
44
|
+
function nextTag(input, isBigTiff) {
|
|
45
|
+
const entrySize = isBigTiff ? CONSTANTS.ENTRY_SIZE.BIG : CONSTANTS.ENTRY_SIZE.STANDARD;
|
|
46
|
+
if (input.length > entrySize) {
|
|
47
|
+
return input.slice(entrySize);
|
|
14
48
|
}
|
|
15
49
|
}
|
|
16
|
-
function extractTags(input, isBigEndian) {
|
|
50
|
+
function extractTags(input, { isBigEndian, isBigTiff }) {
|
|
17
51
|
const tags = {};
|
|
18
52
|
let temp = input;
|
|
19
|
-
while (temp
|
|
53
|
+
while (temp?.length) {
|
|
20
54
|
const code = readUInt(temp, 16, 0, isBigEndian);
|
|
21
55
|
const type = readUInt(temp, 16, 2, isBigEndian);
|
|
22
|
-
const length = readUInt(temp, 32, 4, isBigEndian);
|
|
23
|
-
if (code === 0)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
tags[code] = readValue(temp, isBigEndian);
|
|
28
|
-
}
|
|
29
|
-
temp = nextTag(temp);
|
|
56
|
+
const length = isBigTiff ? Number(readUInt64(temp, 4, isBigEndian)) : readUInt(temp, 32, 4, isBigEndian);
|
|
57
|
+
if (code === 0) break;
|
|
58
|
+
if (length === 1 && (type === CONSTANTS.TYPE.SHORT || type === CONSTANTS.TYPE.LONG || isBigTiff && type === CONSTANTS.TYPE.LONG8)) {
|
|
59
|
+
const valueOffset = isBigTiff ? 12 : 8;
|
|
60
|
+
tags[code] = readTagValue(temp, type, valueOffset, isBigEndian);
|
|
30
61
|
}
|
|
62
|
+
temp = nextTag(temp, isBigTiff);
|
|
31
63
|
}
|
|
32
64
|
return tags;
|
|
33
65
|
}
|
|
34
|
-
function
|
|
66
|
+
function determineFormat(input) {
|
|
35
67
|
const signature = toUTF8String(input, 0, 2);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
68
|
+
const version = readUInt(input, 16, 2, signature === "MM");
|
|
69
|
+
return {
|
|
70
|
+
isBigEndian: signature === "MM",
|
|
71
|
+
isBigTiff: version === 43
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function validateBigTIFFHeader(input, isBigEndian) {
|
|
75
|
+
const byteSize = readUInt(input, 16, 4, isBigEndian);
|
|
76
|
+
const reserved = readUInt(input, 16, 6, isBigEndian);
|
|
77
|
+
if (byteSize !== 8 || reserved !== 0) {
|
|
78
|
+
throw new TypeError("Invalid BigTIFF header");
|
|
40
79
|
}
|
|
41
80
|
}
|
|
42
|
-
const signatures = [
|
|
43
|
-
// '492049', // currently not supported
|
|
81
|
+
const signatures = /* @__PURE__ */ new Set([
|
|
44
82
|
"49492a00",
|
|
45
|
-
// Little
|
|
46
|
-
"4d4d002a"
|
|
83
|
+
// Little Endian
|
|
84
|
+
"4d4d002a",
|
|
47
85
|
// Big Endian
|
|
48
|
-
|
|
49
|
-
|
|
86
|
+
"49492b00",
|
|
87
|
+
// BigTIFF Little Endian
|
|
88
|
+
"4d4d002b"
|
|
89
|
+
// BigTIFF Big Endian
|
|
90
|
+
]);
|
|
50
91
|
const TIFF = {
|
|
51
|
-
validate: (input) =>
|
|
92
|
+
validate: (input) => {
|
|
93
|
+
const signature = toHexString(input, 0, 4);
|
|
94
|
+
return signatures.has(signature);
|
|
95
|
+
},
|
|
52
96
|
calculate(input) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
97
|
+
const format = determineFormat(input);
|
|
98
|
+
if (format.isBigTiff) {
|
|
99
|
+
validateBigTIFFHeader(input, format.isBigEndian);
|
|
100
|
+
}
|
|
101
|
+
const ifdBuffer = readIFD(input, format);
|
|
102
|
+
const tags = extractTags(ifdBuffer, format);
|
|
103
|
+
const info = {
|
|
104
|
+
height: tags[CONSTANTS.TAG.HEIGHT],
|
|
105
|
+
width: tags[CONSTANTS.TAG.WIDTH],
|
|
106
|
+
type: format.isBigTiff ? "bigtiff" : "tiff"
|
|
107
|
+
};
|
|
108
|
+
if (tags[CONSTANTS.TAG.COMPRESSION]) {
|
|
109
|
+
info.compression = tags[CONSTANTS.TAG.COMPRESSION];
|
|
110
|
+
}
|
|
111
|
+
if (!info.width || !info.height) {
|
|
59
112
|
throw new TypeError("Invalid Tiff. Missing tags");
|
|
60
113
|
}
|
|
61
|
-
return
|
|
114
|
+
return info;
|
|
62
115
|
}
|
|
63
116
|
};
|
|
64
117
|
export {
|
|
@@ -7,8 +7,9 @@ export declare const readUInt24LE: (input: Uint8Array, offset?: number) => numbe
|
|
|
7
7
|
export declare const readInt32LE: (input: Uint8Array, offset?: number) => number;
|
|
8
8
|
export declare const readUInt32BE: (input: Uint8Array, offset?: number) => number;
|
|
9
9
|
export declare const readUInt32LE: (input: Uint8Array, offset?: number) => number;
|
|
10
|
-
export declare
|
|
11
|
-
export declare function
|
|
10
|
+
export declare const readUInt64: (input: Uint8Array, offset: number, isBigEndian: boolean) => bigint;
|
|
11
|
+
export declare function readUInt(input: Uint8Array, bits: 16 | 32, offset?: number, isBigEndian?: boolean): number;
|
|
12
|
+
export declare function findBox(input: Uint8Array, boxName: string, currentOffset: number): {
|
|
12
13
|
name: string;
|
|
13
14
|
offset: number;
|
|
14
15
|
size: number;
|