@loaders.gl/images 4.0.0-beta.1 → 4.0.0-beta.3
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/dist/dist.dev.js +749 -0
- package/dist/{esm/image-loader.js → image-loader.js} +3 -3
- package/dist/image-loader.js.map +1 -0
- package/dist/{esm/image-writer.js → image-writer.js} +2 -2
- package/dist/image-writer.js.map +1 -0
- package/dist/index.cjs +686 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/category-api/binary-image-api.d.ts.map +1 -1
- package/dist/{esm/lib → lib}/category-api/binary-image-api.js +1 -1
- package/dist/lib/category-api/binary-image-api.js.map +1 -0
- package/dist/{esm/lib → lib}/category-api/image-format.js +1 -1
- package/dist/lib/category-api/image-format.js.map +1 -0
- package/dist/{esm/lib → lib}/category-api/image-type.js +1 -1
- package/dist/lib/category-api/image-type.js.map +1 -0
- package/dist/lib/category-api/parse-isobmff-binary.js.map +1 -0
- package/dist/lib/category-api/parsed-image-api.js.map +1 -0
- package/dist/{esm/lib → lib}/encoders/encode-image.js +1 -1
- package/dist/lib/encoders/encode-image.js.map +1 -0
- package/dist/{esm/lib → lib}/parsers/parse-image.js +5 -5
- package/dist/lib/parsers/parse-image.js.map +1 -0
- package/dist/{esm/lib → lib}/parsers/parse-to-image-bitmap.js +2 -2
- package/dist/lib/parsers/parse-to-image-bitmap.js.map +1 -0
- package/dist/{esm/lib → lib}/parsers/parse-to-image.js +2 -2
- package/dist/lib/parsers/parse-to-image.js.map +1 -0
- package/dist/{esm/lib → lib}/parsers/parse-to-node-image.js +1 -1
- package/dist/lib/parsers/parse-to-node-image.js.map +1 -0
- package/dist/{esm/lib → lib}/parsers/svg-utils.js +1 -1
- package/dist/lib/parsers/svg-utils.js.map +1 -0
- package/dist/lib/texture-api/async-deep-map.js.map +1 -0
- package/dist/{esm/lib → lib}/texture-api/deep-load.js +1 -1
- package/dist/lib/texture-api/deep-load.js.map +1 -0
- package/dist/{esm/lib → lib}/texture-api/generate-url.js +1 -1
- package/dist/lib/texture-api/generate-url.js.map +1 -0
- package/dist/{esm/lib → lib}/texture-api/load-image.js +4 -4
- package/dist/lib/texture-api/load-image.js.map +1 -0
- package/dist/lib/utils/version.js +2 -0
- package/dist/lib/utils/version.js.map +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +15 -7
- package/src/lib/category-api/binary-image-api.ts +0 -5
- package/dist/bundle.d.ts +0 -2
- package/dist/bundle.d.ts.map +0 -1
- package/dist/dist.min.js +0 -2
- package/dist/dist.min.js.map +0 -7
- package/dist/es5/bundle.js +0 -6
- package/dist/es5/bundle.js.map +0 -1
- package/dist/es5/image-loader.js +0 -32
- package/dist/es5/image-loader.js.map +0 -1
- package/dist/es5/image-writer.js +0 -24
- package/dist/es5/image-writer.js.map +0 -1
- package/dist/es5/index.js +0 -85
- package/dist/es5/index.js.map +0 -1
- package/dist/es5/lib/category-api/binary-image-api.js +0 -113
- package/dist/es5/lib/category-api/binary-image-api.js.map +0 -1
- package/dist/es5/lib/category-api/image-format.js +0 -181
- package/dist/es5/lib/category-api/image-format.js.map +0 -1
- package/dist/es5/lib/category-api/image-type.js +0 -40
- package/dist/es5/lib/category-api/image-type.js.map +0 -1
- package/dist/es5/lib/category-api/parse-isobmff-binary.js +0 -50
- package/dist/es5/lib/category-api/parse-isobmff-binary.js.map +0 -1
- package/dist/es5/lib/category-api/parsed-image-api.js +0 -65
- package/dist/es5/lib/category-api/parsed-image-api.js.map +0 -1
- package/dist/es5/lib/encoders/encode-image.js +0 -101
- package/dist/es5/lib/encoders/encode-image.js.map +0 -1
- package/dist/es5/lib/parsers/parse-image.js +0 -76
- package/dist/es5/lib/parsers/parse-image.js.map +0 -1
- package/dist/es5/lib/parsers/parse-to-image-bitmap.js +0 -97
- package/dist/es5/lib/parsers/parse-to-image-bitmap.js.map +0 -1
- package/dist/es5/lib/parsers/parse-to-image.js +0 -86
- package/dist/es5/lib/parsers/parse-to-image.js.map +0 -1
- package/dist/es5/lib/parsers/parse-to-node-image.js +0 -36
- package/dist/es5/lib/parsers/parse-to-node-image.js.map +0 -1
- package/dist/es5/lib/parsers/svg-utils.js +0 -36
- package/dist/es5/lib/parsers/svg-utils.js.map +0 -1
- package/dist/es5/lib/texture-api/async-deep-map.js +0 -156
- package/dist/es5/lib/texture-api/async-deep-map.js.map +0 -1
- package/dist/es5/lib/texture-api/deep-load.js +0 -63
- package/dist/es5/lib/texture-api/deep-load.js.map +0 -1
- package/dist/es5/lib/texture-api/generate-url.js +0 -24
- package/dist/es5/lib/texture-api/generate-url.js.map +0 -1
- package/dist/es5/lib/texture-api/load-image.js +0 -132
- package/dist/es5/lib/texture-api/load-image.js.map +0 -1
- package/dist/es5/lib/utils/version.js +0 -9
- package/dist/es5/lib/utils/version.js.map +0 -1
- package/dist/es5/types.js +0 -2
- package/dist/es5/types.js.map +0 -1
- package/dist/esm/bundle.js +0 -4
- package/dist/esm/bundle.js.map +0 -1
- package/dist/esm/image-loader.js.map +0 -1
- package/dist/esm/image-writer.js.map +0 -1
- package/dist/esm/index.js +0 -9
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/lib/category-api/binary-image-api.js.map +0 -1
- package/dist/esm/lib/category-api/image-format.js.map +0 -1
- package/dist/esm/lib/category-api/image-type.js.map +0 -1
- package/dist/esm/lib/category-api/parse-isobmff-binary.js.map +0 -1
- package/dist/esm/lib/category-api/parsed-image-api.js.map +0 -1
- package/dist/esm/lib/encoders/encode-image.js.map +0 -1
- package/dist/esm/lib/parsers/parse-image.js.map +0 -1
- package/dist/esm/lib/parsers/parse-to-image-bitmap.js.map +0 -1
- package/dist/esm/lib/parsers/parse-to-image.js.map +0 -1
- package/dist/esm/lib/parsers/parse-to-node-image.js.map +0 -1
- package/dist/esm/lib/parsers/svg-utils.js.map +0 -1
- package/dist/esm/lib/texture-api/async-deep-map.js.map +0 -1
- package/dist/esm/lib/texture-api/deep-load.js.map +0 -1
- package/dist/esm/lib/texture-api/generate-url.js.map +0 -1
- package/dist/esm/lib/texture-api/load-image.js.map +0 -1
- package/dist/esm/lib/utils/version.js +0 -2
- package/dist/esm/lib/utils/version.js.map +0 -1
- package/dist/esm/types.js.map +0 -1
- package/src/bundle.ts +0 -4
- /package/dist/{esm/lib → lib}/category-api/parse-isobmff-binary.js +0 -0
- /package/dist/{esm/lib → lib}/category-api/parsed-image-api.js +0 -0
- /package/dist/{esm/lib → lib}/texture-api/async-deep-map.js +0 -0
- /package/dist/{esm/types.js → types.js} +0 -0
package/dist/dist.dev.js
ADDED
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
+
if (typeof exports === 'object' && typeof module === 'object')
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
5
|
+
else if (typeof exports === 'object') exports['loader'] = factory();
|
|
6
|
+
else root['loader'] = factory();})(globalThis, function () {
|
|
7
|
+
"use strict";
|
|
8
|
+
var __exports__ = (() => {
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
13
|
+
var __export = (target, all) => {
|
|
14
|
+
for (var name in all)
|
|
15
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from))
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
26
|
+
|
|
27
|
+
// src/index.ts
|
|
28
|
+
var src_exports = {};
|
|
29
|
+
__export(src_exports, {
|
|
30
|
+
ImageLoader: () => ImageLoader,
|
|
31
|
+
ImageWriter: () => ImageWriter,
|
|
32
|
+
getBinaryImageMetadata: () => getBinaryImageMetadata,
|
|
33
|
+
getDefaultImageType: () => getDefaultImageType,
|
|
34
|
+
getImageData: () => getImageData,
|
|
35
|
+
getImageSize: () => getImageSize,
|
|
36
|
+
getImageType: () => getImageType,
|
|
37
|
+
getSupportedImageFormats: () => getSupportedImageFormats,
|
|
38
|
+
isImage: () => isImage,
|
|
39
|
+
isImageFormatSupported: () => isImageFormatSupported,
|
|
40
|
+
isImageTypeSupported: () => isImageTypeSupported,
|
|
41
|
+
loadImage: () => loadImage
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// src/lib/utils/version.ts
|
|
45
|
+
var VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
|
|
46
|
+
|
|
47
|
+
// ../loader-utils/src/lib/env-utils/assert.ts
|
|
48
|
+
function assert(condition, message) {
|
|
49
|
+
if (!condition) {
|
|
50
|
+
throw new Error(message || "loader assertion failed.");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ../loader-utils/src/lib/env-utils/globals.ts
|
|
55
|
+
var globals = {
|
|
56
|
+
self: typeof self !== "undefined" && self,
|
|
57
|
+
window: typeof window !== "undefined" && window,
|
|
58
|
+
global: typeof global !== "undefined" && global,
|
|
59
|
+
document: typeof document !== "undefined" && document
|
|
60
|
+
};
|
|
61
|
+
var self_ = globals.self || globals.window || globals.global || {};
|
|
62
|
+
var window_ = globals.window || globals.self || globals.global || {};
|
|
63
|
+
var global_ = globals.global || globals.self || globals.window || {};
|
|
64
|
+
var document_ = globals.document || {};
|
|
65
|
+
var isBrowser = (
|
|
66
|
+
// @ts-ignore process does not exist on browser
|
|
67
|
+
Boolean(typeof process !== "object" || String(process) !== "[object process]" || process.browser)
|
|
68
|
+
);
|
|
69
|
+
var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
|
|
70
|
+
var nodeVersion = matches && parseFloat(matches[1]) || 0;
|
|
71
|
+
|
|
72
|
+
// ../loader-utils/src/lib/path-utils/file-aliases.ts
|
|
73
|
+
var pathPrefix = "";
|
|
74
|
+
var fileAliases = {};
|
|
75
|
+
function resolvePath(filename) {
|
|
76
|
+
for (const alias in fileAliases) {
|
|
77
|
+
if (filename.startsWith(alias)) {
|
|
78
|
+
const replacement = fileAliases[alias];
|
|
79
|
+
filename = filename.replace(alias, replacement);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!filename.startsWith("http://") && !filename.startsWith("https://")) {
|
|
83
|
+
filename = `${pathPrefix}${filename}`;
|
|
84
|
+
}
|
|
85
|
+
return filename;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/lib/category-api/image-type.ts
|
|
89
|
+
var {
|
|
90
|
+
_parseImageNode
|
|
91
|
+
} = globalThis;
|
|
92
|
+
var IMAGE_SUPPORTED = typeof Image !== "undefined";
|
|
93
|
+
var IMAGE_BITMAP_SUPPORTED = typeof ImageBitmap !== "undefined";
|
|
94
|
+
var NODE_IMAGE_SUPPORTED = Boolean(_parseImageNode);
|
|
95
|
+
var DATA_SUPPORTED = isBrowser ? true : NODE_IMAGE_SUPPORTED;
|
|
96
|
+
function isImageTypeSupported(type) {
|
|
97
|
+
switch (type) {
|
|
98
|
+
case "auto":
|
|
99
|
+
return IMAGE_BITMAP_SUPPORTED || IMAGE_SUPPORTED || DATA_SUPPORTED;
|
|
100
|
+
case "imagebitmap":
|
|
101
|
+
return IMAGE_BITMAP_SUPPORTED;
|
|
102
|
+
case "image":
|
|
103
|
+
return IMAGE_SUPPORTED;
|
|
104
|
+
case "data":
|
|
105
|
+
return DATA_SUPPORTED;
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`@loaders.gl/images: image ${type} not supported in this environment`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function getDefaultImageType() {
|
|
111
|
+
if (IMAGE_BITMAP_SUPPORTED) {
|
|
112
|
+
return "imagebitmap";
|
|
113
|
+
}
|
|
114
|
+
if (IMAGE_SUPPORTED) {
|
|
115
|
+
return "image";
|
|
116
|
+
}
|
|
117
|
+
if (DATA_SUPPORTED) {
|
|
118
|
+
return "data";
|
|
119
|
+
}
|
|
120
|
+
throw new Error("Install '@loaders.gl/polyfills' to parse images under Node.js");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/lib/category-api/parsed-image-api.ts
|
|
124
|
+
function isImage(image) {
|
|
125
|
+
return Boolean(getImageTypeOrNull(image));
|
|
126
|
+
}
|
|
127
|
+
function getImageType(image) {
|
|
128
|
+
const format = getImageTypeOrNull(image);
|
|
129
|
+
if (!format) {
|
|
130
|
+
throw new Error("Not an image");
|
|
131
|
+
}
|
|
132
|
+
return format;
|
|
133
|
+
}
|
|
134
|
+
function getImageSize(image) {
|
|
135
|
+
return getImageData(image);
|
|
136
|
+
}
|
|
137
|
+
function getImageData(image) {
|
|
138
|
+
switch (getImageType(image)) {
|
|
139
|
+
case "data":
|
|
140
|
+
return image;
|
|
141
|
+
case "image":
|
|
142
|
+
case "imagebitmap":
|
|
143
|
+
const canvas = document.createElement("canvas");
|
|
144
|
+
const context = canvas.getContext("2d");
|
|
145
|
+
if (!context) {
|
|
146
|
+
throw new Error("getImageData");
|
|
147
|
+
}
|
|
148
|
+
canvas.width = image.width;
|
|
149
|
+
canvas.height = image.height;
|
|
150
|
+
context.drawImage(image, 0, 0);
|
|
151
|
+
return context.getImageData(0, 0, image.width, image.height);
|
|
152
|
+
default:
|
|
153
|
+
throw new Error("getImageData");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function getImageTypeOrNull(image) {
|
|
157
|
+
if (typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) {
|
|
158
|
+
return "imagebitmap";
|
|
159
|
+
}
|
|
160
|
+
if (typeof Image !== "undefined" && image instanceof Image) {
|
|
161
|
+
return "image";
|
|
162
|
+
}
|
|
163
|
+
if (image && typeof image === "object" && image.data && image.width && image.height) {
|
|
164
|
+
return "data";
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/lib/parsers/svg-utils.ts
|
|
170
|
+
var SVG_DATA_URL_PATTERN = /^data:image\/svg\+xml/;
|
|
171
|
+
var SVG_URL_PATTERN = /\.svg((\?|#).*)?$/;
|
|
172
|
+
function isSVG(url) {
|
|
173
|
+
return url && (SVG_DATA_URL_PATTERN.test(url) || SVG_URL_PATTERN.test(url));
|
|
174
|
+
}
|
|
175
|
+
function getBlobOrSVGDataUrl(arrayBuffer, url) {
|
|
176
|
+
if (isSVG(url)) {
|
|
177
|
+
const textDecoder = new TextDecoder();
|
|
178
|
+
let xmlText = textDecoder.decode(arrayBuffer);
|
|
179
|
+
try {
|
|
180
|
+
if (typeof unescape === "function" && typeof encodeURIComponent === "function") {
|
|
181
|
+
xmlText = unescape(encodeURIComponent(xmlText));
|
|
182
|
+
}
|
|
183
|
+
} catch (error) {
|
|
184
|
+
throw new Error(error.message);
|
|
185
|
+
}
|
|
186
|
+
const src = `data:image/svg+xml;base64,${btoa(xmlText)}`;
|
|
187
|
+
return src;
|
|
188
|
+
}
|
|
189
|
+
return getBlob(arrayBuffer, url);
|
|
190
|
+
}
|
|
191
|
+
function getBlob(arrayBuffer, url) {
|
|
192
|
+
if (isSVG(url)) {
|
|
193
|
+
throw new Error("SVG cannot be parsed directly to imagebitmap");
|
|
194
|
+
}
|
|
195
|
+
return new Blob([new Uint8Array(arrayBuffer)]);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/lib/parsers/parse-to-image.ts
|
|
199
|
+
async function parseToImage(arrayBuffer, options, url) {
|
|
200
|
+
const blobOrDataUrl = getBlobOrSVGDataUrl(arrayBuffer, url);
|
|
201
|
+
const URL = self.URL || self.webkitURL;
|
|
202
|
+
const objectUrl = typeof blobOrDataUrl !== "string" && URL.createObjectURL(blobOrDataUrl);
|
|
203
|
+
try {
|
|
204
|
+
return await loadToImage(objectUrl || blobOrDataUrl, options);
|
|
205
|
+
} finally {
|
|
206
|
+
if (objectUrl) {
|
|
207
|
+
URL.revokeObjectURL(objectUrl);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async function loadToImage(url, options) {
|
|
212
|
+
const image = new Image();
|
|
213
|
+
image.src = url;
|
|
214
|
+
if (options.image && options.image.decode && image.decode) {
|
|
215
|
+
await image.decode();
|
|
216
|
+
return image;
|
|
217
|
+
}
|
|
218
|
+
return await new Promise((resolve, reject) => {
|
|
219
|
+
try {
|
|
220
|
+
image.onload = () => resolve(image);
|
|
221
|
+
image.onerror = (err) => reject(new Error(`Could not load image ${url}: ${err}`));
|
|
222
|
+
} catch (error) {
|
|
223
|
+
reject(error);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/lib/parsers/parse-to-image-bitmap.ts
|
|
229
|
+
var EMPTY_OBJECT = {};
|
|
230
|
+
var imagebitmapOptionsSupported = true;
|
|
231
|
+
async function parseToImageBitmap(arrayBuffer, options, url) {
|
|
232
|
+
let blob;
|
|
233
|
+
if (isSVG(url)) {
|
|
234
|
+
const image = await parseToImage(arrayBuffer, options, url);
|
|
235
|
+
blob = image;
|
|
236
|
+
} else {
|
|
237
|
+
blob = getBlob(arrayBuffer, url);
|
|
238
|
+
}
|
|
239
|
+
const imagebitmapOptions = options && options.imagebitmap;
|
|
240
|
+
return await safeCreateImageBitmap(blob, imagebitmapOptions);
|
|
241
|
+
}
|
|
242
|
+
async function safeCreateImageBitmap(blob, imagebitmapOptions = null) {
|
|
243
|
+
if (isEmptyObject(imagebitmapOptions) || !imagebitmapOptionsSupported) {
|
|
244
|
+
imagebitmapOptions = null;
|
|
245
|
+
}
|
|
246
|
+
if (imagebitmapOptions) {
|
|
247
|
+
try {
|
|
248
|
+
return await createImageBitmap(blob, imagebitmapOptions);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.warn(error);
|
|
251
|
+
imagebitmapOptionsSupported = false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return await createImageBitmap(blob);
|
|
255
|
+
}
|
|
256
|
+
function isEmptyObject(object) {
|
|
257
|
+
for (const key in object || EMPTY_OBJECT) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/lib/category-api/parse-isobmff-binary.ts
|
|
264
|
+
function getISOBMFFMediaType(buffer) {
|
|
265
|
+
if (!checkString(buffer, "ftyp", 4)) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
if ((buffer[8] & 96) === 0) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
return decodeMajorBrand(buffer);
|
|
272
|
+
}
|
|
273
|
+
function decodeMajorBrand(buffer) {
|
|
274
|
+
const brandMajor = getUTF8String(buffer, 8, 12).replace("\0", " ").trim();
|
|
275
|
+
switch (brandMajor) {
|
|
276
|
+
case "avif":
|
|
277
|
+
case "avis":
|
|
278
|
+
return {
|
|
279
|
+
extension: "avif",
|
|
280
|
+
mimeType: "image/avif"
|
|
281
|
+
};
|
|
282
|
+
default:
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function getUTF8String(array, start, end) {
|
|
287
|
+
return String.fromCharCode(...array.slice(start, end));
|
|
288
|
+
}
|
|
289
|
+
function stringToBytes(string) {
|
|
290
|
+
return [...string].map((character) => character.charCodeAt(0));
|
|
291
|
+
}
|
|
292
|
+
function checkString(buffer, header, offset = 0) {
|
|
293
|
+
const headerBytes = stringToBytes(header);
|
|
294
|
+
for (let i = 0; i < headerBytes.length; ++i) {
|
|
295
|
+
if (headerBytes[i] !== buffer[i + offset]) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/lib/category-api/binary-image-api.ts
|
|
303
|
+
var BIG_ENDIAN = false;
|
|
304
|
+
var LITTLE_ENDIAN = true;
|
|
305
|
+
function getBinaryImageMetadata(binaryData) {
|
|
306
|
+
const dataView = toDataView(binaryData);
|
|
307
|
+
return getPngMetadata(dataView) || getJpegMetadata(dataView) || getGifMetadata(dataView) || getBmpMetadata(dataView) || getISOBMFFMetadata(dataView);
|
|
308
|
+
}
|
|
309
|
+
function getISOBMFFMetadata(binaryData) {
|
|
310
|
+
const buffer = new Uint8Array(binaryData instanceof DataView ? binaryData.buffer : binaryData);
|
|
311
|
+
const mediaType = getISOBMFFMediaType(buffer);
|
|
312
|
+
if (!mediaType) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
mimeType: mediaType.mimeType,
|
|
317
|
+
// TODO - decode width and height
|
|
318
|
+
width: 0,
|
|
319
|
+
height: 0
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function getPngMetadata(binaryData) {
|
|
323
|
+
const dataView = toDataView(binaryData);
|
|
324
|
+
const isPng = dataView.byteLength >= 24 && dataView.getUint32(0, BIG_ENDIAN) === 2303741511;
|
|
325
|
+
if (!isPng) {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
mimeType: "image/png",
|
|
330
|
+
width: dataView.getUint32(16, BIG_ENDIAN),
|
|
331
|
+
height: dataView.getUint32(20, BIG_ENDIAN)
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function getGifMetadata(binaryData) {
|
|
335
|
+
const dataView = toDataView(binaryData);
|
|
336
|
+
const isGif = dataView.byteLength >= 10 && dataView.getUint32(0, BIG_ENDIAN) === 1195984440;
|
|
337
|
+
if (!isGif) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
mimeType: "image/gif",
|
|
342
|
+
width: dataView.getUint16(6, LITTLE_ENDIAN),
|
|
343
|
+
height: dataView.getUint16(8, LITTLE_ENDIAN)
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function getBmpMetadata(binaryData) {
|
|
347
|
+
const dataView = toDataView(binaryData);
|
|
348
|
+
const isBmp = dataView.byteLength >= 14 && dataView.getUint16(0, BIG_ENDIAN) === 16973 && dataView.getUint32(2, LITTLE_ENDIAN) === dataView.byteLength;
|
|
349
|
+
if (!isBmp) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
mimeType: "image/bmp",
|
|
354
|
+
width: dataView.getUint32(18, LITTLE_ENDIAN),
|
|
355
|
+
height: dataView.getUint32(22, LITTLE_ENDIAN)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function getJpegMetadata(binaryData) {
|
|
359
|
+
const dataView = toDataView(binaryData);
|
|
360
|
+
const isJpeg = dataView.byteLength >= 3 && dataView.getUint16(0, BIG_ENDIAN) === 65496 && dataView.getUint8(2) === 255;
|
|
361
|
+
if (!isJpeg) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
const {
|
|
365
|
+
tableMarkers,
|
|
366
|
+
sofMarkers
|
|
367
|
+
} = getJpegMarkers();
|
|
368
|
+
let i = 2;
|
|
369
|
+
while (i + 9 < dataView.byteLength) {
|
|
370
|
+
const marker = dataView.getUint16(i, BIG_ENDIAN);
|
|
371
|
+
if (sofMarkers.has(marker)) {
|
|
372
|
+
return {
|
|
373
|
+
mimeType: "image/jpeg",
|
|
374
|
+
height: dataView.getUint16(i + 5, BIG_ENDIAN),
|
|
375
|
+
// Number of lines
|
|
376
|
+
width: dataView.getUint16(i + 7, BIG_ENDIAN)
|
|
377
|
+
// Number of pixels per line
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
if (!tableMarkers.has(marker)) {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
i += 2;
|
|
384
|
+
i += dataView.getUint16(i, BIG_ENDIAN);
|
|
385
|
+
}
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
388
|
+
function getJpegMarkers() {
|
|
389
|
+
const tableMarkers = /* @__PURE__ */ new Set([65499, 65476, 65484, 65501, 65534]);
|
|
390
|
+
for (let i = 65504; i < 65520; ++i) {
|
|
391
|
+
tableMarkers.add(i);
|
|
392
|
+
}
|
|
393
|
+
const sofMarkers = /* @__PURE__ */ new Set([65472, 65473, 65474, 65475, 65477, 65478, 65479, 65481, 65482, 65483, 65485, 65486, 65487, 65502]);
|
|
394
|
+
return {
|
|
395
|
+
tableMarkers,
|
|
396
|
+
sofMarkers
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function toDataView(data) {
|
|
400
|
+
if (data instanceof DataView) {
|
|
401
|
+
return data;
|
|
402
|
+
}
|
|
403
|
+
if (ArrayBuffer.isView(data)) {
|
|
404
|
+
return new DataView(data.buffer);
|
|
405
|
+
}
|
|
406
|
+
if (data instanceof ArrayBuffer) {
|
|
407
|
+
return new DataView(data);
|
|
408
|
+
}
|
|
409
|
+
throw new Error("toDataView");
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// src/lib/parsers/parse-to-node-image.ts
|
|
413
|
+
async function parseToNodeImage(arrayBuffer, options) {
|
|
414
|
+
const {
|
|
415
|
+
mimeType
|
|
416
|
+
} = getBinaryImageMetadata(arrayBuffer) || {};
|
|
417
|
+
const _parseImageNode2 = globalThis._parseImageNode;
|
|
418
|
+
assert(_parseImageNode2);
|
|
419
|
+
return await _parseImageNode2(arrayBuffer, mimeType);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// src/lib/parsers/parse-image.ts
|
|
423
|
+
async function parseImage(arrayBuffer, options, context) {
|
|
424
|
+
options = options || {};
|
|
425
|
+
const imageOptions = options.image || {};
|
|
426
|
+
const imageType = imageOptions.type || "auto";
|
|
427
|
+
const {
|
|
428
|
+
url
|
|
429
|
+
} = context || {};
|
|
430
|
+
const loadType = getLoadableImageType(imageType);
|
|
431
|
+
let image;
|
|
432
|
+
switch (loadType) {
|
|
433
|
+
case "imagebitmap":
|
|
434
|
+
image = await parseToImageBitmap(arrayBuffer, options, url);
|
|
435
|
+
break;
|
|
436
|
+
case "image":
|
|
437
|
+
image = await parseToImage(arrayBuffer, options, url);
|
|
438
|
+
break;
|
|
439
|
+
case "data":
|
|
440
|
+
image = await parseToNodeImage(arrayBuffer, options);
|
|
441
|
+
break;
|
|
442
|
+
default:
|
|
443
|
+
assert(false);
|
|
444
|
+
}
|
|
445
|
+
if (imageType === "data") {
|
|
446
|
+
image = getImageData(image);
|
|
447
|
+
}
|
|
448
|
+
return image;
|
|
449
|
+
}
|
|
450
|
+
function getLoadableImageType(type) {
|
|
451
|
+
switch (type) {
|
|
452
|
+
case "auto":
|
|
453
|
+
case "data":
|
|
454
|
+
return getDefaultImageType();
|
|
455
|
+
default:
|
|
456
|
+
isImageTypeSupported(type);
|
|
457
|
+
return type;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/image-loader.ts
|
|
462
|
+
var EXTENSIONS = ["png", "jpg", "jpeg", "gif", "webp", "bmp", "ico", "svg", "avif"];
|
|
463
|
+
var MIME_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp", "image/avif", "image/bmp", "image/vnd.microsoft.icon", "image/svg+xml"];
|
|
464
|
+
var DEFAULT_IMAGE_LOADER_OPTIONS = {
|
|
465
|
+
image: {
|
|
466
|
+
type: "auto",
|
|
467
|
+
decode: true
|
|
468
|
+
// if format is HTML
|
|
469
|
+
}
|
|
470
|
+
// imagebitmap: {} - passes (platform dependent) parameters to ImageBitmap constructor
|
|
471
|
+
};
|
|
472
|
+
var ImageLoader = {
|
|
473
|
+
id: "image",
|
|
474
|
+
module: "images",
|
|
475
|
+
name: "Images",
|
|
476
|
+
version: VERSION,
|
|
477
|
+
mimeTypes: MIME_TYPES,
|
|
478
|
+
extensions: EXTENSIONS,
|
|
479
|
+
parse: parseImage,
|
|
480
|
+
// TODO: byteOffset, byteLength;
|
|
481
|
+
tests: [(arrayBuffer) => Boolean(getBinaryImageMetadata(new DataView(arrayBuffer)))],
|
|
482
|
+
options: DEFAULT_IMAGE_LOADER_OPTIONS
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
// src/lib/encoders/encode-image.ts
|
|
486
|
+
var {
|
|
487
|
+
_encodeImageNode
|
|
488
|
+
} = globalThis;
|
|
489
|
+
async function encodeImage(image, options) {
|
|
490
|
+
options = options || {};
|
|
491
|
+
options.image = options.image || {};
|
|
492
|
+
return _encodeImageNode ? _encodeImageNode(image, {
|
|
493
|
+
type: options.image.mimeType
|
|
494
|
+
}) : encodeImageInBrowser(image, options);
|
|
495
|
+
}
|
|
496
|
+
var qualityParamSupported = true;
|
|
497
|
+
async function encodeImageInBrowser(image, options) {
|
|
498
|
+
const {
|
|
499
|
+
mimeType,
|
|
500
|
+
jpegQuality
|
|
501
|
+
} = options.image;
|
|
502
|
+
const {
|
|
503
|
+
width,
|
|
504
|
+
height
|
|
505
|
+
} = getImageSize(image);
|
|
506
|
+
const canvas = document.createElement("canvas");
|
|
507
|
+
canvas.width = width;
|
|
508
|
+
canvas.height = height;
|
|
509
|
+
drawImageToCanvas(image, canvas);
|
|
510
|
+
const blob = await new Promise((resolve) => {
|
|
511
|
+
if (jpegQuality && qualityParamSupported) {
|
|
512
|
+
try {
|
|
513
|
+
canvas.toBlob(resolve, mimeType, jpegQuality);
|
|
514
|
+
return;
|
|
515
|
+
} catch (error) {
|
|
516
|
+
qualityParamSupported = false;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
canvas.toBlob(resolve, mimeType);
|
|
520
|
+
});
|
|
521
|
+
if (!blob) {
|
|
522
|
+
throw new Error("image encoding failed");
|
|
523
|
+
}
|
|
524
|
+
return await blob.arrayBuffer();
|
|
525
|
+
}
|
|
526
|
+
function drawImageToCanvas(image, canvas, x = 0, y = 0) {
|
|
527
|
+
if (x === 0 && y === 0 && typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) {
|
|
528
|
+
const context2 = canvas.getContext("bitmaprenderer");
|
|
529
|
+
if (context2) {
|
|
530
|
+
context2.transferFromImageBitmap(image);
|
|
531
|
+
return canvas;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const context = canvas.getContext("2d");
|
|
535
|
+
if (image.data) {
|
|
536
|
+
const clampedArray = new Uint8ClampedArray(image.data);
|
|
537
|
+
const imageData = new ImageData(clampedArray, image.width, image.height);
|
|
538
|
+
context.putImageData(imageData, 0, 0);
|
|
539
|
+
return canvas;
|
|
540
|
+
}
|
|
541
|
+
context.drawImage(image, 0, 0);
|
|
542
|
+
return canvas;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// src/image-writer.ts
|
|
546
|
+
var ImageWriter = {
|
|
547
|
+
name: "Images",
|
|
548
|
+
id: "image",
|
|
549
|
+
module: "images",
|
|
550
|
+
version: VERSION,
|
|
551
|
+
extensions: ["jpeg"],
|
|
552
|
+
options: {
|
|
553
|
+
image: {
|
|
554
|
+
mimeType: "image/png",
|
|
555
|
+
jpegQuality: null
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
encode: encodeImage
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
// src/lib/category-api/image-format.ts
|
|
562
|
+
var MIME_TYPES2 = [
|
|
563
|
+
"image/png",
|
|
564
|
+
"image/jpeg",
|
|
565
|
+
"image/gif",
|
|
566
|
+
"image/webp",
|
|
567
|
+
"image/avif",
|
|
568
|
+
"image/tiff",
|
|
569
|
+
// TODO - what is the correct type for SVG
|
|
570
|
+
"image/svg",
|
|
571
|
+
"image/svg+xml",
|
|
572
|
+
"image/bmp",
|
|
573
|
+
"image/vnd.microsoft.icon"
|
|
574
|
+
];
|
|
575
|
+
var mimeTypeSupportedPromise = null;
|
|
576
|
+
async function getSupportedImageFormats() {
|
|
577
|
+
if (mimeTypeSupportedPromise) {
|
|
578
|
+
return await mimeTypeSupportedPromise;
|
|
579
|
+
}
|
|
580
|
+
const supportedMimeTypes = /* @__PURE__ */ new Set();
|
|
581
|
+
for (const mimeType of MIME_TYPES2) {
|
|
582
|
+
const supported = isBrowser ? await checkBrowserImageFormatSupportAsync(mimeType) : checkNodeImageFormatSupport(mimeType);
|
|
583
|
+
if (supported) {
|
|
584
|
+
supportedMimeTypes.add(mimeType);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return supportedMimeTypes;
|
|
588
|
+
}
|
|
589
|
+
var mimeTypeSupportedSync = {};
|
|
590
|
+
function isImageFormatSupported(mimeType) {
|
|
591
|
+
if (mimeTypeSupportedSync[mimeType] === void 0) {
|
|
592
|
+
const supported = isBrowser ? checkBrowserImageFormatSupport(mimeType) : checkNodeImageFormatSupport(mimeType);
|
|
593
|
+
mimeTypeSupportedSync[mimeType] = supported;
|
|
594
|
+
}
|
|
595
|
+
return mimeTypeSupportedSync[mimeType];
|
|
596
|
+
}
|
|
597
|
+
function checkNodeImageFormatSupport(mimeType) {
|
|
598
|
+
const NODE_FORMAT_SUPPORT = ["image/png", "image/jpeg", "image/gif"];
|
|
599
|
+
const {
|
|
600
|
+
_parseImageNode: _parseImageNode2,
|
|
601
|
+
_imageFormatsNode = NODE_FORMAT_SUPPORT
|
|
602
|
+
} = globalThis;
|
|
603
|
+
return Boolean(_parseImageNode2) && _imageFormatsNode.includes(mimeType);
|
|
604
|
+
}
|
|
605
|
+
function checkBrowserImageFormatSupport(mimeType) {
|
|
606
|
+
switch (mimeType) {
|
|
607
|
+
case "image/avif":
|
|
608
|
+
case "image/webp":
|
|
609
|
+
return testBrowserImageFormatSupport(mimeType);
|
|
610
|
+
default:
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
var TEST_IMAGE = {
|
|
615
|
+
"image/avif": "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=",
|
|
616
|
+
// Lossy test image. Support for lossy images doesn't guarantee support for all WebP images.
|
|
617
|
+
"image/webp": "data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA"
|
|
618
|
+
};
|
|
619
|
+
async function checkBrowserImageFormatSupportAsync(mimeType) {
|
|
620
|
+
const dataURL = TEST_IMAGE[mimeType];
|
|
621
|
+
return dataURL ? await testBrowserImageFormatSupportAsync(dataURL) : true;
|
|
622
|
+
}
|
|
623
|
+
function testBrowserImageFormatSupport(mimeType) {
|
|
624
|
+
try {
|
|
625
|
+
const element = document.createElement("canvas");
|
|
626
|
+
const dataURL = element.toDataURL(mimeType);
|
|
627
|
+
return dataURL.indexOf(`data:${mimeType}`) === 0;
|
|
628
|
+
} catch {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
async function testBrowserImageFormatSupportAsync(testImageDataURL) {
|
|
633
|
+
return new Promise((resolve) => {
|
|
634
|
+
const image = new Image();
|
|
635
|
+
image.src = testImageDataURL;
|
|
636
|
+
image.onload = () => resolve(image.height > 0);
|
|
637
|
+
image.onerror = () => resolve(false);
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// src/lib/texture-api/generate-url.ts
|
|
642
|
+
function generateUrl(getUrl, options, urlOptions) {
|
|
643
|
+
let url = getUrl;
|
|
644
|
+
if (typeof getUrl === "function") {
|
|
645
|
+
url = getUrl({
|
|
646
|
+
...options,
|
|
647
|
+
...urlOptions
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
assert(typeof url === "string");
|
|
651
|
+
const {
|
|
652
|
+
baseUrl
|
|
653
|
+
} = options;
|
|
654
|
+
if (baseUrl) {
|
|
655
|
+
url = baseUrl[baseUrl.length - 1] === "/" ? `${baseUrl}${url}` : `${baseUrl}/${url}`;
|
|
656
|
+
}
|
|
657
|
+
return resolvePath(url);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// src/lib/texture-api/async-deep-map.ts
|
|
661
|
+
var isObject = (value) => value && typeof value === "object";
|
|
662
|
+
async function asyncDeepMap(tree, func, options = {}) {
|
|
663
|
+
return await mapSubtree(tree, func, options);
|
|
664
|
+
}
|
|
665
|
+
async function mapSubtree(object, func, options) {
|
|
666
|
+
if (Array.isArray(object)) {
|
|
667
|
+
return await mapArray(object, func, options);
|
|
668
|
+
}
|
|
669
|
+
if (isObject(object)) {
|
|
670
|
+
return await mapObject(object, func, options);
|
|
671
|
+
}
|
|
672
|
+
const url = object;
|
|
673
|
+
return await func(url, options);
|
|
674
|
+
}
|
|
675
|
+
async function mapObject(object, func, options) {
|
|
676
|
+
const promises = [];
|
|
677
|
+
const values = {};
|
|
678
|
+
for (const key in object) {
|
|
679
|
+
const url = object[key];
|
|
680
|
+
const promise = mapSubtree(url, func, options).then((value) => {
|
|
681
|
+
values[key] = value;
|
|
682
|
+
});
|
|
683
|
+
promises.push(promise);
|
|
684
|
+
}
|
|
685
|
+
await Promise.all(promises);
|
|
686
|
+
return values;
|
|
687
|
+
}
|
|
688
|
+
async function mapArray(urlArray, func, options = {}) {
|
|
689
|
+
const promises = urlArray.map((url) => mapSubtree(url, func, options));
|
|
690
|
+
return await Promise.all(promises);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// src/lib/texture-api/deep-load.ts
|
|
694
|
+
async function deepLoad(urlTree, load, options) {
|
|
695
|
+
return await asyncDeepMap(urlTree, (url) => shallowLoad(url, load, options));
|
|
696
|
+
}
|
|
697
|
+
async function shallowLoad(url, load, options) {
|
|
698
|
+
const response = await fetch(url, options.fetch);
|
|
699
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
700
|
+
return await load(arrayBuffer, options);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// src/lib/texture-api/load-image.ts
|
|
704
|
+
async function loadImage(getUrl, options = {}) {
|
|
705
|
+
const imageUrls = await getImageUrls(getUrl, options);
|
|
706
|
+
return await deepLoad(imageUrls, parseImage, options);
|
|
707
|
+
}
|
|
708
|
+
async function getImageUrls(getUrl, options, urlOptions = {}) {
|
|
709
|
+
const mipLevels = options && options.image && options.image.mipLevels || 0;
|
|
710
|
+
return mipLevels !== 0 ? await getMipmappedImageUrls(getUrl, mipLevels, options, urlOptions) : generateUrl(getUrl, options, urlOptions);
|
|
711
|
+
}
|
|
712
|
+
async function getMipmappedImageUrls(getUrl, mipLevels, options, urlOptions) {
|
|
713
|
+
const urls = [];
|
|
714
|
+
if (mipLevels === "auto") {
|
|
715
|
+
const url = generateUrl(getUrl, options, {
|
|
716
|
+
...urlOptions,
|
|
717
|
+
lod: 0
|
|
718
|
+
});
|
|
719
|
+
const image = await shallowLoad(url, parseImage, options);
|
|
720
|
+
const {
|
|
721
|
+
width,
|
|
722
|
+
height
|
|
723
|
+
} = getImageSize(image);
|
|
724
|
+
mipLevels = getMipLevels({
|
|
725
|
+
width,
|
|
726
|
+
height
|
|
727
|
+
});
|
|
728
|
+
urls.push(url);
|
|
729
|
+
}
|
|
730
|
+
assert(mipLevels > 0);
|
|
731
|
+
for (let mipLevel = urls.length; mipLevel < mipLevels; ++mipLevel) {
|
|
732
|
+
const url = generateUrl(getUrl, options, {
|
|
733
|
+
...urlOptions,
|
|
734
|
+
lod: mipLevel
|
|
735
|
+
});
|
|
736
|
+
urls.push(url);
|
|
737
|
+
}
|
|
738
|
+
return urls;
|
|
739
|
+
}
|
|
740
|
+
function getMipLevels({
|
|
741
|
+
width,
|
|
742
|
+
height
|
|
743
|
+
}) {
|
|
744
|
+
return 1 + Math.floor(Math.log2(Math.max(width, height)));
|
|
745
|
+
}
|
|
746
|
+
return __toCommonJS(src_exports);
|
|
747
|
+
})();
|
|
748
|
+
return __exports__;
|
|
749
|
+
});
|