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