astro 4.3.7 → 4.4.0
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/Image.astro +4 -0
- package/components/Picture.astro +4 -0
- package/dist/assets/internal.js +14 -0
- package/dist/assets/types.d.ts +23 -2
- package/dist/assets/utils/metadata.js +3 -3
- package/dist/assets/utils/remoteProbe.d.ts +2 -0
- package/dist/assets/utils/remoteProbe.js +35 -0
- package/dist/assets/utils/vendor/image-size/detector.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/detector.js +24 -0
- package/dist/assets/utils/vendor/image-size/lookup.d.ts +10 -0
- package/dist/assets/utils/vendor/image-size/lookup.js +26 -0
- package/dist/assets/utils/vendor/image-size/types/bmp.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/bmp.js +11 -0
- package/dist/assets/utils/vendor/image-size/types/cur.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/cur.js +17 -0
- package/dist/assets/utils/vendor/image-size/types/dds.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/dds.js +11 -0
- package/dist/assets/utils/vendor/image-size/types/gif.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/gif.js +12 -0
- package/dist/assets/utils/vendor/image-size/types/heif.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/heif.js +53 -0
- package/dist/assets/utils/vendor/image-size/types/icns.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/icns.js +85 -0
- package/dist/assets/utils/vendor/image-size/types/ico.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/ico.js +43 -0
- package/dist/assets/utils/vendor/image-size/types/index.d.ts +3 -0
- package/dist/assets/utils/vendor/image-size/types/index.js +43 -0
- package/dist/assets/utils/vendor/image-size/types/interface.d.ts +13 -0
- package/dist/assets/utils/vendor/image-size/types/interface.js +0 -0
- package/dist/assets/utils/vendor/image-size/types/j2c.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/j2c.js +12 -0
- package/dist/assets/utils/vendor/image-size/types/jp2.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jp2.js +25 -0
- package/dist/assets/utils/vendor/image-size/types/jpg.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jpg.js +97 -0
- package/dist/assets/utils/vendor/image-size/types/ktx.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/ktx.js +19 -0
- package/dist/assets/utils/vendor/image-size/types/png.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/png.js +34 -0
- package/dist/assets/utils/vendor/image-size/types/pnm.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/pnm.js +69 -0
- package/dist/assets/utils/vendor/image-size/types/psd.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/psd.js +11 -0
- package/dist/assets/utils/vendor/image-size/types/svg.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/svg.js +94 -0
- package/dist/assets/utils/vendor/image-size/types/tga.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/tga.js +15 -0
- package/dist/assets/utils/vendor/image-size/types/tiff.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/tiff.js +66 -0
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +15 -0
- package/dist/assets/utils/vendor/image-size/types/utils.js +60 -0
- package/dist/assets/utils/vendor/image-size/types/webp.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/webp.js +52 -0
- package/dist/cli/add/index.js +9 -2
- package/dist/content/runtime.js +3 -1
- package/dist/content/types-generator.js +3 -23
- package/dist/core/build/plugins/plugin-css.js +6 -5
- package/dist/core/build/plugins/plugin-hoisted-scripts.js +6 -5
- package/dist/core/build/plugins/util.d.ts +2 -1
- package/dist/core/build/plugins/util.js +12 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/errors-data.d.ts +16 -3
- package/dist/core/errors/errors-data.js +9 -2
- package/dist/core/messages.js +2 -2
- package/dist/core/routing/manifest/create.js +11 -27
- package/dist/prerender/routing.js +20 -20
- package/dist/runtime/client/dev-toolbar/apps/astro.js +1 -1
- package/dist/runtime/client/dev-toolbar/apps/audit/index.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/audit/index.js +115 -6
- package/dist/runtime/client/dev-toolbar/apps/audit/perf.d.ts +2 -0
- package/dist/runtime/client/dev-toolbar/apps/audit/perf.js +110 -0
- package/dist/runtime/client/dev-toolbar/apps/utils/highlight.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/utils/highlight.js +6 -1
- package/dist/runtime/client/dev-toolbar/ui-library/card.js +1 -1
- package/dist/runtime/server/astro-island.js +10 -1
- package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +7 -0
- package/dist/runtime/server/astro-island.prebuilt-dev.js +4 -0
- package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
- package/dist/runtime/server/astro-island.prebuilt.js +1 -1
- package/dist/runtime/server/render/astro/render.d.ts +1 -0
- package/dist/runtime/server/render/astro/render.js +81 -2
- package/dist/runtime/server/render/component.js +6 -0
- package/dist/runtime/server/render/page.js +15 -2
- package/dist/runtime/server/render/util.d.ts +7 -0
- package/dist/runtime/server/render/util.js +15 -0
- package/dist/runtime/server/scripts.js +2 -4
- package/dist/runtime/server/transition.js +14 -1
- package/package.json +5 -5
package/components/Image.astro
CHANGED
|
@@ -29,6 +29,10 @@ const additionalAttributes: HTMLAttributes<'img'> = {};
|
|
|
29
29
|
if (image.srcSet.values.length > 0) {
|
|
30
30
|
additionalAttributes.srcset = image.srcSet.attribute;
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
if (import.meta.env.DEV) {
|
|
34
|
+
additionalAttributes['data-image-component'] = 'true';
|
|
35
|
+
}
|
|
32
36
|
---
|
|
33
37
|
|
|
34
38
|
<img src={image.src} {...additionalAttributes} {...image.attributes} />
|
package/components/Picture.astro
CHANGED
|
@@ -61,6 +61,10 @@ if (props.sizes) {
|
|
|
61
61
|
if (fallbackImage.srcSet.values.length > 0) {
|
|
62
62
|
imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
if (import.meta.env.DEV) {
|
|
66
|
+
imgAdditionalAttributes['data-image-component'] = 'true';
|
|
67
|
+
}
|
|
64
68
|
---
|
|
65
69
|
|
|
66
70
|
<picture {...pictureAttributes}>
|
package/dist/assets/internal.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
|
|
2
2
|
import { DEFAULT_HASH_PROPS } from "./consts.js";
|
|
3
3
|
import { isLocalService } from "./services/service.js";
|
|
4
4
|
import { isESMImportedImage, isRemoteImage } from "./utils/imageKind.js";
|
|
5
|
+
import { probe } from "./utils/remoteProbe.js";
|
|
5
6
|
async function getConfiguredImageService() {
|
|
6
7
|
if (!globalThis?.astroAsset?.imageService) {
|
|
7
8
|
const { default: service } = await import(
|
|
@@ -41,6 +42,19 @@ async function getImage(options, imageConfig) {
|
|
|
41
42
|
...options,
|
|
42
43
|
src: typeof options.src === "object" && "then" in options.src ? (await options.src).default ?? await options.src : options.src
|
|
43
44
|
};
|
|
45
|
+
if (options.inferSize && isRemoteImage(resolvedOptions.src)) {
|
|
46
|
+
try {
|
|
47
|
+
const result = await probe(resolvedOptions.src);
|
|
48
|
+
resolvedOptions.width ??= result.width;
|
|
49
|
+
resolvedOptions.height ??= result.height;
|
|
50
|
+
delete resolvedOptions.inferSize;
|
|
51
|
+
} catch {
|
|
52
|
+
throw new AstroError({
|
|
53
|
+
...AstroErrorData.FailedToFetchRemoteImageDimensions,
|
|
54
|
+
message: AstroErrorData.FailedToFetchRemoteImageDimensions.message(resolvedOptions.src)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
44
58
|
const originalPath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : resolvedOptions.src;
|
|
45
59
|
const clonedSrc = isESMImportedImage(resolvedOptions.src) ? (
|
|
46
60
|
// @ts-expect-error - clone is a private, hidden prop
|
package/dist/assets/types.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export type UnresolvedImageTransform = Omit<ImageTransform, 'src'> & {
|
|
|
48
48
|
src: ImageMetadata | string | Promise<{
|
|
49
49
|
default: ImageMetadata;
|
|
50
50
|
}>;
|
|
51
|
+
inferSize?: boolean;
|
|
51
52
|
};
|
|
52
53
|
/**
|
|
53
54
|
* Options accepted by the image transformation service.
|
|
@@ -159,7 +160,7 @@ export type LocalImageProps<T> = ImageSharedProps<T> & {
|
|
|
159
160
|
*/
|
|
160
161
|
quality?: ImageQuality;
|
|
161
162
|
};
|
|
162
|
-
export type RemoteImageProps<T> =
|
|
163
|
+
export type RemoteImageProps<T> = (ImageSharedProps<T> & {
|
|
163
164
|
/**
|
|
164
165
|
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
|
|
165
166
|
*
|
|
@@ -171,5 +172,25 @@ export type RemoteImageProps<T> = WithRequired<ImageSharedProps<T>, 'width' | 'h
|
|
|
171
172
|
* ```
|
|
172
173
|
*/
|
|
173
174
|
src: string;
|
|
174
|
-
|
|
175
|
+
/**
|
|
176
|
+
* When inferSize is true width and height are not required
|
|
177
|
+
*/
|
|
178
|
+
inferSize: true;
|
|
179
|
+
}) | (WithRequired<ImageSharedProps<T>, 'width' | 'height'> & {
|
|
180
|
+
/**
|
|
181
|
+
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
|
|
182
|
+
*
|
|
183
|
+
* Remote images are not optimized, and require both `width` and `height` to be set.
|
|
184
|
+
*
|
|
185
|
+
* **Example**:
|
|
186
|
+
* ```
|
|
187
|
+
* <Image src="https://example.com/image.png" width={450} height={300} alt="..." />
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
src: string;
|
|
191
|
+
/**
|
|
192
|
+
* When inferSize is false or undefined width and height are required
|
|
193
|
+
*/
|
|
194
|
+
inferSize?: false | undefined;
|
|
195
|
+
});
|
|
175
196
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import probe from "
|
|
1
|
+
import { lookup as probe } from "../utils/vendor/image-size/lookup.js";
|
|
2
2
|
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
|
|
3
3
|
async function imageMetadata(data, src) {
|
|
4
|
-
const result = probe
|
|
5
|
-
if (result
|
|
4
|
+
const result = probe(data);
|
|
5
|
+
if (!result.height || !result.width || !result.type) {
|
|
6
6
|
throw new AstroError({
|
|
7
7
|
...AstroErrorData.NoImageMetadata,
|
|
8
8
|
message: AstroErrorData.NoImageMetadata.message(src)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { lookup } from "./vendor/image-size/lookup.js";
|
|
2
|
+
async function probe(url) {
|
|
3
|
+
const response = await fetch(url);
|
|
4
|
+
if (!response.body || !response.ok) {
|
|
5
|
+
throw new Error("Failed to fetch image");
|
|
6
|
+
}
|
|
7
|
+
const reader = response.body.getReader();
|
|
8
|
+
let done, value;
|
|
9
|
+
let accumulatedChunks = new Uint8Array();
|
|
10
|
+
while (!done) {
|
|
11
|
+
const readResult = await reader.read();
|
|
12
|
+
done = readResult.done;
|
|
13
|
+
if (done)
|
|
14
|
+
break;
|
|
15
|
+
if (readResult.value) {
|
|
16
|
+
value = readResult.value;
|
|
17
|
+
let tmp = new Uint8Array(accumulatedChunks.length + value.length);
|
|
18
|
+
tmp.set(accumulatedChunks, 0);
|
|
19
|
+
tmp.set(value, accumulatedChunks.length);
|
|
20
|
+
accumulatedChunks = tmp;
|
|
21
|
+
try {
|
|
22
|
+
const dimensions = lookup(accumulatedChunks);
|
|
23
|
+
if (dimensions) {
|
|
24
|
+
await reader.cancel();
|
|
25
|
+
return dimensions;
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new Error("Failed to parse the size");
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
probe
|
|
35
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { typeHandlers, types } from "./types/index.js";
|
|
2
|
+
const firstBytes = /* @__PURE__ */ new Map([
|
|
3
|
+
[56, "psd"],
|
|
4
|
+
[66, "bmp"],
|
|
5
|
+
[68, "dds"],
|
|
6
|
+
[71, "gif"],
|
|
7
|
+
[73, "tiff"],
|
|
8
|
+
[77, "tiff"],
|
|
9
|
+
[82, "webp"],
|
|
10
|
+
[105, "icns"],
|
|
11
|
+
[137, "png"],
|
|
12
|
+
[255, "jpg"]
|
|
13
|
+
]);
|
|
14
|
+
function detector(input) {
|
|
15
|
+
const byte = input[0];
|
|
16
|
+
const type = firstBytes.get(byte);
|
|
17
|
+
if (type && typeHandlers.get(type).validate(input)) {
|
|
18
|
+
return type;
|
|
19
|
+
}
|
|
20
|
+
return types.find((fileType) => typeHandlers.get(fileType).validate(input));
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
detector
|
|
24
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { imageType } from './types/index.js';
|
|
2
|
+
import type { ISizeCalculationResult } from './types/interface.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Return size information based on an Uint8Array
|
|
5
|
+
*
|
|
6
|
+
* @param {Uint8Array} input
|
|
7
|
+
* @returns {ISizeCalculationResult}
|
|
8
|
+
*/
|
|
9
|
+
export declare function lookup(input: Uint8Array): ISizeCalculationResult;
|
|
10
|
+
export declare const disableTypes: (types: imageType[]) => void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { typeHandlers } from "./types/index.js";
|
|
2
|
+
import { detector } from "./detector.js";
|
|
3
|
+
const globalOptions = {
|
|
4
|
+
disabledTypes: []
|
|
5
|
+
};
|
|
6
|
+
function lookup(input) {
|
|
7
|
+
const type = detector(input);
|
|
8
|
+
if (typeof type !== "undefined") {
|
|
9
|
+
if (globalOptions.disabledTypes.indexOf(type) > -1) {
|
|
10
|
+
throw new TypeError("disabled file type: " + type);
|
|
11
|
+
}
|
|
12
|
+
const size = typeHandlers.get(type).calculate(input);
|
|
13
|
+
if (size !== void 0) {
|
|
14
|
+
size.type = size.type ?? type;
|
|
15
|
+
return size;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
throw new TypeError("unsupported file type: " + type);
|
|
19
|
+
}
|
|
20
|
+
const disableTypes = (types) => {
|
|
21
|
+
globalOptions.disabledTypes = types;
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
disableTypes,
|
|
25
|
+
lookup
|
|
26
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { toUTF8String, readInt32LE, readUInt32LE } from "./utils.js";
|
|
2
|
+
const BMP = {
|
|
3
|
+
validate: (input) => toUTF8String(input, 0, 2) === "BM",
|
|
4
|
+
calculate: (input) => ({
|
|
5
|
+
height: Math.abs(readInt32LE(input, 22)),
|
|
6
|
+
width: readUInt32LE(input, 18)
|
|
7
|
+
})
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
BMP
|
|
11
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ICO } from "./ico.js";
|
|
2
|
+
import { readUInt16LE } from "./utils.js";
|
|
3
|
+
const TYPE_CURSOR = 2;
|
|
4
|
+
const CUR = {
|
|
5
|
+
validate(input) {
|
|
6
|
+
const reserved = readUInt16LE(input, 0);
|
|
7
|
+
const imageCount = readUInt16LE(input, 4);
|
|
8
|
+
if (reserved !== 0 || imageCount === 0)
|
|
9
|
+
return false;
|
|
10
|
+
const imageType = readUInt16LE(input, 2);
|
|
11
|
+
return imageType === TYPE_CURSOR;
|
|
12
|
+
},
|
|
13
|
+
calculate: (input) => ICO.calculate(input)
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
CUR
|
|
17
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { toUTF8String, readUInt16LE } from "./utils.js";
|
|
2
|
+
const gifRegexp = /^GIF8[79]a/;
|
|
3
|
+
const GIF = {
|
|
4
|
+
validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)),
|
|
5
|
+
calculate: (input) => ({
|
|
6
|
+
height: readUInt16LE(input, 8),
|
|
7
|
+
width: readUInt16LE(input, 6)
|
|
8
|
+
})
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
GIF
|
|
12
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { findBox, readUInt32BE, toUTF8String } from "./utils.js";
|
|
2
|
+
const brandMap = {
|
|
3
|
+
avif: "avif",
|
|
4
|
+
mif1: "heif",
|
|
5
|
+
msf1: "heif",
|
|
6
|
+
// hief-sequence
|
|
7
|
+
heic: "heic",
|
|
8
|
+
heix: "heic",
|
|
9
|
+
hevc: "heic",
|
|
10
|
+
// heic-sequence
|
|
11
|
+
hevx: "heic"
|
|
12
|
+
// heic-sequence
|
|
13
|
+
};
|
|
14
|
+
function detectBrands(buffer, start, end) {
|
|
15
|
+
let brandsDetected = {};
|
|
16
|
+
for (let i = start; i <= end; i += 4) {
|
|
17
|
+
const brand = toUTF8String(buffer, i, i + 4);
|
|
18
|
+
if (brand in brandMap) {
|
|
19
|
+
brandsDetected[brand] = 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if ("avif" in brandsDetected) {
|
|
23
|
+
return "avif";
|
|
24
|
+
} else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) {
|
|
25
|
+
return "heic";
|
|
26
|
+
} else if ("mif1" in brandsDetected || "msf1" in brandsDetected) {
|
|
27
|
+
return "heif";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const HEIF = {
|
|
31
|
+
validate(buffer) {
|
|
32
|
+
const ftype = toUTF8String(buffer, 4, 8);
|
|
33
|
+
const brand = toUTF8String(buffer, 8, 12);
|
|
34
|
+
return "ftyp" === ftype && brand in brandMap;
|
|
35
|
+
},
|
|
36
|
+
calculate(buffer) {
|
|
37
|
+
const metaBox = findBox(buffer, "meta", 0);
|
|
38
|
+
const iprpBox = metaBox && findBox(buffer, "iprp", metaBox.offset + 12);
|
|
39
|
+
const ipcoBox = iprpBox && findBox(buffer, "ipco", iprpBox.offset + 8);
|
|
40
|
+
const ispeBox = ipcoBox && findBox(buffer, "ispe", ipcoBox.offset + 8);
|
|
41
|
+
if (ispeBox) {
|
|
42
|
+
return {
|
|
43
|
+
height: readUInt32BE(buffer, ispeBox.offset + 16),
|
|
44
|
+
width: readUInt32BE(buffer, ispeBox.offset + 12),
|
|
45
|
+
type: detectBrands(buffer, 8, metaBox.offset)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
throw new TypeError("Invalid HEIF, no size found");
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
HEIF
|
|
53
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { toUTF8String, readUInt32BE } from "./utils.js";
|
|
2
|
+
const SIZE_HEADER = 4 + 4;
|
|
3
|
+
const FILE_LENGTH_OFFSET = 4;
|
|
4
|
+
const ENTRY_LENGTH_OFFSET = 4;
|
|
5
|
+
const ICON_TYPE_SIZE = {
|
|
6
|
+
ICON: 32,
|
|
7
|
+
"ICN#": 32,
|
|
8
|
+
// m => 16 x 16
|
|
9
|
+
"icm#": 16,
|
|
10
|
+
icm4: 16,
|
|
11
|
+
icm8: 16,
|
|
12
|
+
// s => 16 x 16
|
|
13
|
+
"ics#": 16,
|
|
14
|
+
ics4: 16,
|
|
15
|
+
ics8: 16,
|
|
16
|
+
is32: 16,
|
|
17
|
+
s8mk: 16,
|
|
18
|
+
icp4: 16,
|
|
19
|
+
// l => 32 x 32
|
|
20
|
+
icl4: 32,
|
|
21
|
+
icl8: 32,
|
|
22
|
+
il32: 32,
|
|
23
|
+
l8mk: 32,
|
|
24
|
+
icp5: 32,
|
|
25
|
+
ic11: 32,
|
|
26
|
+
// h => 48 x 48
|
|
27
|
+
ich4: 48,
|
|
28
|
+
ich8: 48,
|
|
29
|
+
ih32: 48,
|
|
30
|
+
h8mk: 48,
|
|
31
|
+
// . => 64 x 64
|
|
32
|
+
icp6: 64,
|
|
33
|
+
ic12: 32,
|
|
34
|
+
// t => 128 x 128
|
|
35
|
+
it32: 128,
|
|
36
|
+
t8mk: 128,
|
|
37
|
+
ic07: 128,
|
|
38
|
+
// . => 256 x 256
|
|
39
|
+
ic08: 256,
|
|
40
|
+
ic13: 256,
|
|
41
|
+
// . => 512 x 512
|
|
42
|
+
ic09: 512,
|
|
43
|
+
ic14: 512,
|
|
44
|
+
// . => 1024 x 1024
|
|
45
|
+
ic10: 1024
|
|
46
|
+
};
|
|
47
|
+
function readImageHeader(input, imageOffset) {
|
|
48
|
+
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
|
|
49
|
+
return [
|
|
50
|
+
toUTF8String(input, imageOffset, imageLengthOffset),
|
|
51
|
+
readUInt32BE(input, imageLengthOffset)
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
function getImageSize(type) {
|
|
55
|
+
const size = ICON_TYPE_SIZE[type];
|
|
56
|
+
return { width: size, height: size, type };
|
|
57
|
+
}
|
|
58
|
+
const ICNS = {
|
|
59
|
+
validate: (input) => toUTF8String(input, 0, 4) === "icns",
|
|
60
|
+
calculate(input) {
|
|
61
|
+
const inputLength = input.length;
|
|
62
|
+
const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET);
|
|
63
|
+
let imageOffset = SIZE_HEADER;
|
|
64
|
+
let imageHeader = readImageHeader(input, imageOffset);
|
|
65
|
+
let imageSize = getImageSize(imageHeader[0]);
|
|
66
|
+
imageOffset += imageHeader[1];
|
|
67
|
+
if (imageOffset === fileLength)
|
|
68
|
+
return imageSize;
|
|
69
|
+
const result = {
|
|
70
|
+
height: imageSize.height,
|
|
71
|
+
images: [imageSize],
|
|
72
|
+
width: imageSize.width
|
|
73
|
+
};
|
|
74
|
+
while (imageOffset < fileLength && imageOffset < inputLength) {
|
|
75
|
+
imageHeader = readImageHeader(input, imageOffset);
|
|
76
|
+
imageSize = getImageSize(imageHeader[0]);
|
|
77
|
+
imageOffset += imageHeader[1];
|
|
78
|
+
result.images.push(imageSize);
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
export {
|
|
84
|
+
ICNS
|
|
85
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readUInt16LE } from "./utils.js";
|
|
2
|
+
const TYPE_ICON = 1;
|
|
3
|
+
const SIZE_HEADER = 2 + 2 + 2;
|
|
4
|
+
const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4;
|
|
5
|
+
function getSizeFromOffset(input, offset) {
|
|
6
|
+
const value = input[offset];
|
|
7
|
+
return value === 0 ? 256 : value;
|
|
8
|
+
}
|
|
9
|
+
function getImageSize(input, imageIndex) {
|
|
10
|
+
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY;
|
|
11
|
+
return {
|
|
12
|
+
height: getSizeFromOffset(input, offset + 1),
|
|
13
|
+
width: getSizeFromOffset(input, offset)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const ICO = {
|
|
17
|
+
validate(input) {
|
|
18
|
+
const reserved = readUInt16LE(input, 0);
|
|
19
|
+
const imageCount = readUInt16LE(input, 4);
|
|
20
|
+
if (reserved !== 0 || imageCount === 0)
|
|
21
|
+
return false;
|
|
22
|
+
const imageType = readUInt16LE(input, 2);
|
|
23
|
+
return imageType === TYPE_ICON;
|
|
24
|
+
},
|
|
25
|
+
calculate(input) {
|
|
26
|
+
const nbImages = readUInt16LE(input, 4);
|
|
27
|
+
const imageSize = getImageSize(input, 0);
|
|
28
|
+
if (nbImages === 1)
|
|
29
|
+
return imageSize;
|
|
30
|
+
const imgs = [imageSize];
|
|
31
|
+
for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) {
|
|
32
|
+
imgs.push(getImageSize(input, imageIndex));
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
height: imageSize.height,
|
|
36
|
+
images: imgs,
|
|
37
|
+
width: imageSize.width
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export {
|
|
42
|
+
ICO
|
|
43
|
+
};
|
|
@@ -0,0 +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];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BMP } from "./bmp.js";
|
|
2
|
+
import { CUR } from "./cur.js";
|
|
3
|
+
import { DDS } from "./dds.js";
|
|
4
|
+
import { GIF } from "./gif.js";
|
|
5
|
+
import { HEIF } from "./heif.js";
|
|
6
|
+
import { ICNS } from "./icns.js";
|
|
7
|
+
import { ICO } from "./ico.js";
|
|
8
|
+
import { J2C } from "./j2c.js";
|
|
9
|
+
import { JP2 } from "./jp2.js";
|
|
10
|
+
import { JPG } from "./jpg.js";
|
|
11
|
+
import { KTX } from "./ktx.js";
|
|
12
|
+
import { PNG } from "./png.js";
|
|
13
|
+
import { PNM } from "./pnm.js";
|
|
14
|
+
import { PSD } from "./psd.js";
|
|
15
|
+
import { SVG } from "./svg.js";
|
|
16
|
+
import { TGA } from "./tga.js";
|
|
17
|
+
import { TIFF } from "./tiff.js";
|
|
18
|
+
import { WEBP } from "./webp.js";
|
|
19
|
+
const typeHandlers = /* @__PURE__ */ new Map([
|
|
20
|
+
["bmp", BMP],
|
|
21
|
+
["cur", CUR],
|
|
22
|
+
["dds", DDS],
|
|
23
|
+
["gif", GIF],
|
|
24
|
+
["heif", HEIF],
|
|
25
|
+
["icns", ICNS],
|
|
26
|
+
["ico", ICO],
|
|
27
|
+
["j2c", J2C],
|
|
28
|
+
["jp2", JP2],
|
|
29
|
+
["jpg", JPG],
|
|
30
|
+
["ktx", KTX],
|
|
31
|
+
["png", PNG],
|
|
32
|
+
["pnm", PNM],
|
|
33
|
+
["psd", PSD],
|
|
34
|
+
["svg", SVG],
|
|
35
|
+
["tga", TGA],
|
|
36
|
+
["tiff", TIFF],
|
|
37
|
+
["webp", WEBP]
|
|
38
|
+
]);
|
|
39
|
+
const types = Array.from(typeHandlers.keys());
|
|
40
|
+
export {
|
|
41
|
+
typeHandlers,
|
|
42
|
+
types
|
|
43
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ISize = {
|
|
2
|
+
width: number | undefined;
|
|
3
|
+
height: number | undefined;
|
|
4
|
+
orientation?: number;
|
|
5
|
+
type?: string;
|
|
6
|
+
};
|
|
7
|
+
export type ISizeCalculationResult = {
|
|
8
|
+
images?: ISize[];
|
|
9
|
+
} & ISize;
|
|
10
|
+
export type IImage = {
|
|
11
|
+
validate: (input: Uint8Array) => boolean;
|
|
12
|
+
calculate: (input: Uint8Array) => ISizeCalculationResult;
|
|
13
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { toHexString, readUInt32BE } from "./utils.js";
|
|
2
|
+
const J2C = {
|
|
3
|
+
// TODO: this doesn't seem right. SIZ marker doesn't have to be right after the SOC
|
|
4
|
+
validate: (input) => toHexString(input, 0, 4) === "ff4fff51",
|
|
5
|
+
calculate: (input) => ({
|
|
6
|
+
height: readUInt32BE(input, 12),
|
|
7
|
+
width: readUInt32BE(input, 8)
|
|
8
|
+
})
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
J2C
|
|
12
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readUInt32BE, findBox } from "./utils.js";
|
|
2
|
+
const JP2 = {
|
|
3
|
+
validate(input) {
|
|
4
|
+
if (readUInt32BE(input, 4) !== 1783636e3 || readUInt32BE(input, 0) < 1)
|
|
5
|
+
return false;
|
|
6
|
+
const ftypBox = findBox(input, "ftyp", 0);
|
|
7
|
+
if (!ftypBox)
|
|
8
|
+
return false;
|
|
9
|
+
return readUInt32BE(input, ftypBox.offset + 4) === 1718909296;
|
|
10
|
+
},
|
|
11
|
+
calculate(input) {
|
|
12
|
+
const jp2hBox = findBox(input, "jp2h", 0);
|
|
13
|
+
const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8);
|
|
14
|
+
if (ihdrBox) {
|
|
15
|
+
return {
|
|
16
|
+
height: readUInt32BE(input, ihdrBox.offset + 8),
|
|
17
|
+
width: readUInt32BE(input, ihdrBox.offset + 12)
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
throw new TypeError("Unsupported JPEG 2000 format");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
JP2
|
|
25
|
+
};
|