@loaders.gl/images 4.2.0-alpha.4 → 4.2.0-alpha.6

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 (57) hide show
  1. package/dist/dist.dev.js +87 -40
  2. package/dist/dist.min.js +9 -0
  3. package/dist/image-loader.d.ts +1 -1
  4. package/dist/image-loader.d.ts.map +1 -1
  5. package/dist/image-loader.js +30 -15
  6. package/dist/image-writer.d.ts +1 -1
  7. package/dist/image-writer.d.ts.map +1 -1
  8. package/dist/image-writer.js +16 -13
  9. package/dist/index.cjs +23 -22
  10. package/dist/index.cjs.map +7 -0
  11. package/dist/index.d.ts +9 -9
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +8 -2
  14. package/dist/lib/category-api/binary-image-api.js +131 -86
  15. package/dist/lib/category-api/image-format.js +86 -46
  16. package/dist/lib/category-api/image-type.d.ts +1 -1
  17. package/dist/lib/category-api/image-type.d.ts.map +1 -1
  18. package/dist/lib/category-api/image-type.js +35 -26
  19. package/dist/lib/category-api/parse-isobmff-binary.js +81 -29
  20. package/dist/lib/category-api/parsed-image-api.d.ts +1 -1
  21. package/dist/lib/category-api/parsed-image-api.d.ts.map +1 -1
  22. package/dist/lib/category-api/parsed-image-api.js +49 -41
  23. package/dist/lib/encoders/encode-image.d.ts +1 -1
  24. package/dist/lib/encoders/encode-image.d.ts.map +1 -1
  25. package/dist/lib/encoders/encode-image.js +67 -51
  26. package/dist/lib/parsers/parse-image.d.ts +2 -2
  27. package/dist/lib/parsers/parse-image.d.ts.map +1 -1
  28. package/dist/lib/parsers/parse-image.js +41 -34
  29. package/dist/lib/parsers/parse-to-image-bitmap.d.ts +1 -1
  30. package/dist/lib/parsers/parse-to-image-bitmap.d.ts.map +1 -1
  31. package/dist/lib/parsers/parse-to-image-bitmap.js +45 -27
  32. package/dist/lib/parsers/parse-to-image.d.ts +1 -1
  33. package/dist/lib/parsers/parse-to-image.d.ts.map +1 -1
  34. package/dist/lib/parsers/parse-to-image.js +38 -26
  35. package/dist/lib/parsers/parse-to-node-image.d.ts +2 -2
  36. package/dist/lib/parsers/parse-to-node-image.d.ts.map +1 -1
  37. package/dist/lib/parsers/parse-to-node-image.js +7 -8
  38. package/dist/lib/parsers/svg-utils.js +27 -19
  39. package/dist/lib/utils/version.js +4 -2
  40. package/dist/types.js +0 -1
  41. package/package.json +10 -6
  42. package/dist/image-loader.js.map +0 -1
  43. package/dist/image-writer.js.map +0 -1
  44. package/dist/index.js.map +0 -1
  45. package/dist/lib/category-api/binary-image-api.js.map +0 -1
  46. package/dist/lib/category-api/image-format.js.map +0 -1
  47. package/dist/lib/category-api/image-type.js.map +0 -1
  48. package/dist/lib/category-api/parse-isobmff-binary.js.map +0 -1
  49. package/dist/lib/category-api/parsed-image-api.js.map +0 -1
  50. package/dist/lib/encoders/encode-image.js.map +0 -1
  51. package/dist/lib/parsers/parse-image.js.map +0 -1
  52. package/dist/lib/parsers/parse-to-image-bitmap.js.map +0 -1
  53. package/dist/lib/parsers/parse-to-image.js.map +0 -1
  54. package/dist/lib/parsers/parse-to-node-image.js.map +0 -1
  55. package/dist/lib/parsers/svg-utils.js.map +0 -1
  56. package/dist/lib/utils/version.js.map +0 -1
  57. package/dist/types.js.map +0 -1
@@ -1,34 +1,43 @@
1
- var _globalThis$loaders;
2
1
  import { isBrowser } from '@loaders.gl/loader-utils';
3
- const parseImageNode = (_globalThis$loaders = globalThis.loaders) === null || _globalThis$loaders === void 0 ? void 0 : _globalThis$loaders.parseImageNode;
4
- const IMAGE_SUPPORTED = typeof Image !== 'undefined';
2
+ // @ts-ignore TS2339: Property does not exist on type
3
+ const parseImageNode = globalThis.loaders?.parseImageNode;
4
+ const IMAGE_SUPPORTED = typeof Image !== 'undefined'; // NOTE: "false" positives if jsdom is installed
5
5
  const IMAGE_BITMAP_SUPPORTED = typeof ImageBitmap !== 'undefined';
6
6
  const NODE_IMAGE_SUPPORTED = Boolean(parseImageNode);
7
7
  const DATA_SUPPORTED = isBrowser ? true : NODE_IMAGE_SUPPORTED;
8
+ /**
9
+ * Checks if a loaders.gl image type is supported
10
+ * @param type image type string
11
+ */
8
12
  export function isImageTypeSupported(type) {
9
- switch (type) {
10
- case 'auto':
11
- return IMAGE_BITMAP_SUPPORTED || IMAGE_SUPPORTED || DATA_SUPPORTED;
12
- case 'imagebitmap':
13
- return IMAGE_BITMAP_SUPPORTED;
14
- case 'image':
15
- return IMAGE_SUPPORTED;
16
- case 'data':
17
- return DATA_SUPPORTED;
18
- default:
19
- throw new Error(`@loaders.gl/images: image ${type} not supported in this environment`);
20
- }
13
+ switch (type) {
14
+ case 'auto':
15
+ // Should only ever be false in Node.js, if polyfills have not been installed...
16
+ return IMAGE_BITMAP_SUPPORTED || IMAGE_SUPPORTED || DATA_SUPPORTED;
17
+ case 'imagebitmap':
18
+ return IMAGE_BITMAP_SUPPORTED;
19
+ case 'image':
20
+ return IMAGE_SUPPORTED;
21
+ case 'data':
22
+ return DATA_SUPPORTED;
23
+ default:
24
+ throw new Error(`@loaders.gl/images: image ${type} not supported in this environment`);
25
+ }
21
26
  }
27
+ /**
28
+ * Returns the "most performant" supported image type on this platform
29
+ * @returns image type string
30
+ */
22
31
  export function getDefaultImageType() {
23
- if (IMAGE_BITMAP_SUPPORTED) {
24
- return 'imagebitmap';
25
- }
26
- if (IMAGE_SUPPORTED) {
27
- return 'image';
28
- }
29
- if (DATA_SUPPORTED) {
30
- return 'data';
31
- }
32
- throw new Error('Install \'@loaders.gl/polyfills\' to parse images under Node.js');
32
+ if (IMAGE_BITMAP_SUPPORTED) {
33
+ return 'imagebitmap';
34
+ }
35
+ if (IMAGE_SUPPORTED) {
36
+ return 'image';
37
+ }
38
+ if (DATA_SUPPORTED) {
39
+ return 'data';
40
+ }
41
+ // This should only happen in Node.js
42
+ throw new Error('Install \'@loaders.gl/polyfills\' to parse images under Node.js');
33
43
  }
34
- //# sourceMappingURL=image-type.js.map
@@ -1,39 +1,91 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ // code adapted from https://github.com/sindresorhus/file-type under MIT license
5
+ /**
6
+ * Tests if a buffer is in ISO base media file format (ISOBMFF) @see https://en.wikipedia.org/wiki/ISO_base_media_file_format
7
+ * (ISOBMFF is a media container standard based on the Apple QuickTime container format)
8
+ */
1
9
  export function getISOBMFFMediaType(buffer) {
2
- if (!checkString(buffer, 'ftyp', 4)) {
3
- return null;
4
- }
5
- if ((buffer[8] & 0x60) === 0x00) {
6
- return null;
7
- }
8
- return decodeMajorBrand(buffer);
10
+ // Almost all ISO base media files start with `ftyp` box. (It's not required to be first, but it's recommended to be.)
11
+ if (!checkString(buffer, 'ftyp', 4)) {
12
+ return null;
13
+ }
14
+ // Extra check: test for 8859-1 printable characters (for simplicity, it's a mask which also catches one non-printable character).
15
+ if ((buffer[8] & 0x60) === 0x00) {
16
+ return null;
17
+ }
18
+ // `ftyp` box must contain a brand major identifier, which must consist of ISO 8859-1 printable characters.
19
+ return decodeMajorBrand(buffer);
9
20
  }
21
+ /**
22
+ * brands explained @see https://github.com/strukturag/libheif/issues/83
23
+ * code adapted from @see https://github.com/sindresorhus/file-type/blob/main/core.js#L489-L492
24
+ */
10
25
  export function decodeMajorBrand(buffer) {
11
- const brandMajor = getUTF8String(buffer, 8, 12).replace('\0', ' ').trim();
12
- switch (brandMajor) {
13
- case 'avif':
14
- case 'avis':
15
- return {
16
- extension: 'avif',
17
- mimeType: 'image/avif'
18
- };
19
- default:
20
- return null;
21
- }
26
+ const brandMajor = getUTF8String(buffer, 8, 12).replace('\0', ' ').trim();
27
+ switch (brandMajor) {
28
+ case 'avif':
29
+ case 'avis':
30
+ return { extension: 'avif', mimeType: 'image/avif' };
31
+ default:
32
+ return null;
33
+ }
34
+ // We don't need these now, but they are easy to add
35
+ // case 'mif1':
36
+ // return {extension: 'heic', mimeType: 'image/heif'};
37
+ // case 'msf1':
38
+ // return {extension: 'heic', mimeType: 'image/heif-sequence'};
39
+ // case 'heic':
40
+ // case 'heix':
41
+ // return {extension: 'heic', mimeType: 'image/heic'};
42
+ // case 'hevc':
43
+ // case 'hevx':
44
+ // return {extension: 'heic', mimeType: 'image/heic-sequence'};
45
+ // case 'qt':
46
+ // return {ext: 'mov', mime: 'video/quicktime'};
47
+ // case 'M4V':
48
+ // case 'M4VH':
49
+ // case 'M4VP':
50
+ // return {ext: 'm4v', mime: 'video/x-m4v'};
51
+ // case 'M4P':
52
+ // return {ext: 'm4p', mime: 'video/mp4'};
53
+ // case 'M4B':
54
+ // return {ext: 'm4b', mime: 'audio/mp4'};
55
+ // case 'M4A':
56
+ // return {ext: 'm4a', mime: 'audio/x-m4a'};
57
+ // case 'F4V':
58
+ // return {ext: 'f4v', mime: 'video/mp4'};
59
+ // case 'F4P':
60
+ // return {ext: 'f4p', mime: 'video/mp4'};
61
+ // case 'F4A':
62
+ // return {ext: 'f4a', mime: 'audio/mp4'};
63
+ // case 'F4B':
64
+ // return {ext: 'f4b', mime: 'audio/mp4'};
65
+ // case 'crx':
66
+ // return {ext: 'cr3', mime: 'image/x-canon-cr3'};
67
+ // default:
68
+ // if (brandMajor.startsWith('3g')) {
69
+ // if (brandMajor.startsWith('3g2')) {
70
+ // return {ext: '3g2', mime: 'video/3gpp2'};
71
+ // }
72
+ // return {ext: '3gp', mime: 'video/3gpp'};
73
+ // }
74
+ // return {ext: 'mp4', mime: 'video/mp4'};
22
75
  }
76
+ /** Interpret a chunk of bytes as a UTF8 string */
23
77
  function getUTF8String(array, start, end) {
24
- return String.fromCharCode(...array.slice(start, end));
78
+ return String.fromCharCode(...array.slice(start, end));
25
79
  }
26
80
  function stringToBytes(string) {
27
- return [...string].map(character => character.charCodeAt(0));
81
+ return [...string].map((character) => character.charCodeAt(0));
28
82
  }
29
- function checkString(buffer, header) {
30
- let offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
31
- const headerBytes = stringToBytes(header);
32
- for (let i = 0; i < headerBytes.length; ++i) {
33
- if (headerBytes[i] !== buffer[i + offset]) {
34
- return false;
83
+ function checkString(buffer, header, offset = 0) {
84
+ const headerBytes = stringToBytes(header);
85
+ for (let i = 0; i < headerBytes.length; ++i) {
86
+ if (headerBytes[i] !== buffer[i + offset]) {
87
+ return false;
88
+ }
35
89
  }
36
- }
37
- return true;
90
+ return true;
38
91
  }
39
- //# sourceMappingURL=parse-isobmff-binary.js.map
@@ -1,4 +1,4 @@
1
- import type { ImageType, ImageTypeEnum, ImageDataType } from '../../types';
1
+ import type { ImageType, ImageTypeEnum, ImageDataType } from "../../types.js";
2
2
  export declare function isImage(image: ImageType): boolean;
3
3
  export declare function deleteImage(image: ImageType): void;
4
4
  export declare function getImageType(image: ImageType): ImageTypeEnum;
@@ -1 +1 @@
1
- {"version":3,"file":"parsed-image-api.d.ts","sourceRoot":"","sources":["../../../src/lib/category-api/parsed-image-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,aAAa,EAAE,aAAa,EAAC,MAAM,aAAa,CAAC;AAEzE,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEjD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAQlD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAM5D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAE9E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CA0BxE"}
1
+ {"version":3,"file":"parsed-image-api.d.ts","sourceRoot":"","sources":["../../../src/lib/category-api/parsed-image-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,aAAa,EAAE,aAAa,EAAC,uBAAoB;AAEzE,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEjD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAQlD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAM5D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAE9E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CA0BxE"}
@@ -1,53 +1,61 @@
1
1
  export function isImage(image) {
2
- return Boolean(getImageTypeOrNull(image));
2
+ return Boolean(getImageTypeOrNull(image));
3
3
  }
4
4
  export function deleteImage(image) {
5
- switch (getImageType(image)) {
6
- case 'imagebitmap':
7
- image.close();
8
- break;
9
- default:
10
- }
5
+ switch (getImageType(image)) {
6
+ case 'imagebitmap':
7
+ image.close();
8
+ break;
9
+ default:
10
+ // Nothing to do for images and image data objects
11
+ }
11
12
  }
12
13
  export function getImageType(image) {
13
- const format = getImageTypeOrNull(image);
14
- if (!format) {
15
- throw new Error('Not an image');
16
- }
17
- return format;
14
+ const format = getImageTypeOrNull(image);
15
+ if (!format) {
16
+ throw new Error('Not an image');
17
+ }
18
+ return format;
18
19
  }
19
20
  export function getImageSize(image) {
20
- return getImageData(image);
21
+ return getImageData(image);
21
22
  }
22
23
  export function getImageData(image) {
23
- switch (getImageType(image)) {
24
- case 'data':
25
- return image;
26
- case 'image':
27
- case 'imagebitmap':
28
- const canvas = document.createElement('canvas');
29
- const context = canvas.getContext('2d');
30
- if (!context) {
31
- throw new Error('getImageData');
32
- }
33
- canvas.width = image.width;
34
- canvas.height = image.height;
35
- context.drawImage(image, 0, 0);
36
- return context.getImageData(0, 0, image.width, image.height);
37
- default:
38
- throw new Error('getImageData');
39
- }
24
+ switch (getImageType(image)) {
25
+ case 'data':
26
+ return image;
27
+ case 'image':
28
+ case 'imagebitmap':
29
+ // Extract the image data from the image via a canvas
30
+ const canvas = document.createElement('canvas');
31
+ // TODO - reuse the canvas?
32
+ const context = canvas.getContext('2d');
33
+ if (!context) {
34
+ throw new Error('getImageData');
35
+ }
36
+ // @ts-ignore
37
+ canvas.width = image.width;
38
+ // @ts-ignore
39
+ canvas.height = image.height;
40
+ // @ts-ignore
41
+ context.drawImage(image, 0, 0);
42
+ // @ts-ignore
43
+ return context.getImageData(0, 0, image.width, image.height);
44
+ default:
45
+ throw new Error('getImageData');
46
+ }
40
47
  }
48
+ // PRIVATE
49
+ // eslint-disable-next-line complexity
41
50
  function getImageTypeOrNull(image) {
42
- if (typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
43
- return 'imagebitmap';
44
- }
45
- if (typeof Image !== 'undefined' && image instanceof Image) {
46
- return 'image';
47
- }
48
- if (image && typeof image === 'object' && image.data && image.width && image.height) {
49
- return 'data';
50
- }
51
- return null;
51
+ if (typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
52
+ return 'imagebitmap';
53
+ }
54
+ if (typeof Image !== 'undefined' && image instanceof Image) {
55
+ return 'image';
56
+ }
57
+ if (image && typeof image === 'object' && image.data && image.width && image.height) {
58
+ return 'data';
59
+ }
60
+ return null;
52
61
  }
53
- //# sourceMappingURL=parsed-image-api.js.map
@@ -1,4 +1,4 @@
1
- import { ImageDataType } from '../../types';
1
+ import { ImageDataType } from "../../types.js";
2
2
  /**
3
3
  * Returns data bytes representing a compressed image in PNG or JPG format,
4
4
  * This data can be saved using file system (f) methods or used in a request.
@@ -1 +1 @@
1
- {"version":3,"file":"encode-image.d.ts","sourceRoot":"","sources":["../../../src/lib/encoders/encode-image.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAC;AAM1C;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,GAC7B,OAAO,CAAC,WAAW,CAAC,CAOtB"}
1
+ {"version":3,"file":"encode-image.d.ts","sourceRoot":"","sources":["../../../src/lib/encoders/encode-image.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,uBAAoB;AAM1C;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,GAC7B,OAAO,CAAC,WAAW,CAAC,CAOtB"}
@@ -1,61 +1,77 @@
1
- var _globalThis$loaders;
2
1
  import { getImageSize } from "../category-api/parsed-image-api.js";
3
- const encodeImageNode = (_globalThis$loaders = globalThis.loaders) === null || _globalThis$loaders === void 0 ? void 0 : _globalThis$loaders.encodeImageNode;
2
+ // @ts-ignore TS2339: Property does not exist on type
3
+ const encodeImageNode = globalThis.loaders?.encodeImageNode;
4
+ /**
5
+ * Returns data bytes representing a compressed image in PNG or JPG format,
6
+ * This data can be saved using file system (f) methods or used in a request.
7
+ * @param image - ImageBitmap Image or Canvas
8
+ * @param options
9
+ * param opt.type='png' - png, jpg or image/png, image/jpg are valid
10
+ * param mimeType= - Whether to include a data URI header
11
+ */
4
12
  export async function encodeImage(image, options) {
5
- options = options || {};
6
- options.image = options.image || {};
7
- return encodeImageNode ? encodeImageNode(image, {
8
- type: options.image.mimeType
9
- }) : encodeImageInBrowser(image, options);
13
+ options = options || {};
14
+ options.image = options.image || {};
15
+ return encodeImageNode
16
+ ? encodeImageNode(image, { type: options.image.mimeType })
17
+ : encodeImageInBrowser(image, options);
10
18
  }
19
+ // In case we get exceptions from canvas.toBlob(resolve, type, quality)
11
20
  let qualityParamSupported = true;
21
+ /**
22
+ *
23
+ * @param image
24
+ * @param options
25
+ * @note Based on canvas.toBlob
26
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
27
+ */
12
28
  async function encodeImageInBrowser(image, options) {
13
- const {
14
- mimeType,
15
- jpegQuality
16
- } = options.image;
17
- const {
18
- width,
19
- height
20
- } = getImageSize(image);
21
- const canvas = document.createElement('canvas');
22
- canvas.width = width;
23
- canvas.height = height;
24
- drawImageToCanvas(image, canvas);
25
- const blob = await new Promise(resolve => {
26
- if (jpegQuality && qualityParamSupported) {
27
- try {
28
- canvas.toBlob(resolve, mimeType, jpegQuality);
29
- return;
30
- } catch (error) {
31
- qualityParamSupported = false;
32
- }
29
+ const { mimeType, jpegQuality } = options.image;
30
+ const { width, height } = getImageSize(image);
31
+ // create a canvas and resize it to the size of our image
32
+ const canvas = document.createElement('canvas');
33
+ canvas.width = width;
34
+ canvas.height = height;
35
+ drawImageToCanvas(image, canvas);
36
+ // The actual encoding is done asynchronously with `canvas.toBlob()`
37
+ const blob = await new Promise((resolve) => {
38
+ // get it back as a Blob
39
+ if (jpegQuality && qualityParamSupported) {
40
+ try {
41
+ canvas.toBlob(resolve, mimeType, jpegQuality);
42
+ return;
43
+ }
44
+ catch (error) {
45
+ qualityParamSupported = false;
46
+ }
47
+ }
48
+ canvas.toBlob(resolve, mimeType);
49
+ });
50
+ if (!blob) {
51
+ throw new Error('image encoding failed');
33
52
  }
34
- canvas.toBlob(resolve, mimeType);
35
- });
36
- if (!blob) {
37
- throw new Error('image encoding failed');
38
- }
39
- return await blob.arrayBuffer();
53
+ return await blob.arrayBuffer();
40
54
  }
41
- function drawImageToCanvas(image, canvas) {
42
- let x = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
43
- let y = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
44
- if (x === 0 && y === 0 && typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
45
- const context = canvas.getContext('bitmaprenderer');
46
- if (context) {
47
- context.transferFromImageBitmap(image);
48
- return canvas;
55
+ function drawImageToCanvas(image, canvas, x = 0, y = 0) {
56
+ // Try optimized path for ImageBitmaps via bitmaprenderer context
57
+ if (x === 0 && y === 0 && typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
58
+ const context = canvas.getContext('bitmaprenderer');
59
+ if (context) {
60
+ // transfer the ImageBitmap to it
61
+ context.transferFromImageBitmap(image);
62
+ return canvas;
63
+ }
49
64
  }
50
- }
51
- const context = canvas.getContext('2d');
52
- if (image.data) {
53
- const clampedArray = new Uint8ClampedArray(image.data);
54
- const imageData = new ImageData(clampedArray, image.width, image.height);
55
- context.putImageData(imageData, 0, 0);
65
+ // Available on most platforms, except IE11 and Andriod WebViews...
66
+ const context = canvas.getContext('2d');
67
+ if (image.data) {
68
+ // ImageData constructor expects clamped array even though getImageData does not return a clamped array...
69
+ const clampedArray = new Uint8ClampedArray(image.data);
70
+ const imageData = new ImageData(clampedArray, image.width, image.height);
71
+ context.putImageData(imageData, 0, 0);
72
+ return canvas;
73
+ }
74
+ // Fall back to generic image/image bitmap rendering path
75
+ context.drawImage(image, 0, 0);
56
76
  return canvas;
57
- }
58
- context.drawImage(image, 0, 0);
59
- return canvas;
60
77
  }
61
- //# sourceMappingURL=encode-image.js.map
@@ -1,5 +1,5 @@
1
1
  import type { LoaderContext } from '@loaders.gl/loader-utils';
2
- import type { ImageType } from '../../types';
3
- import type { ImageLoaderOptions } from '../../image-loader';
2
+ import type { ImageType } from "../../types.js";
3
+ import type { ImageLoaderOptions } from "../../image-loader.js";
4
4
  export declare function parseImage(arrayBuffer: ArrayBuffer, options?: ImageLoaderOptions, context?: LoaderContext): Promise<ImageType>;
5
5
  //# sourceMappingURL=parse-image.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-image.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAS3D,wBAAsB,UAAU,CAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,CAAC,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,SAAS,CAAC,CAkCpB"}
1
+ {"version":3,"file":"parse-image.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAC,SAAS,EAAC,uBAAoB;AAC3C,OAAO,KAAK,EAAC,kBAAkB,EAAC,8BAA2B;AAS3D,wBAAsB,UAAU,CAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,CAAC,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,SAAS,CAAC,CAkCpB"}
@@ -4,41 +4,48 @@ import { getImageData } from "../category-api/parsed-image-api.js";
4
4
  import { parseToImage } from "./parse-to-image.js";
5
5
  import { parseToImageBitmap } from "./parse-to-image-bitmap.js";
6
6
  import { parseToNodeImage } from "./parse-to-node-image.js";
7
+ // Parse to platform defined image type (data on node, ImageBitmap or HTMLImage on browser)
8
+ // eslint-disable-next-line complexity
7
9
  export async function parseImage(arrayBuffer, options, context) {
8
- options = options || {};
9
- const imageOptions = options.image || {};
10
- const imageType = imageOptions.type || 'auto';
11
- const {
12
- url
13
- } = context || {};
14
- const loadType = getLoadableImageType(imageType);
15
- let image;
16
- switch (loadType) {
17
- case 'imagebitmap':
18
- image = await parseToImageBitmap(arrayBuffer, options, url);
19
- break;
20
- case 'image':
21
- image = await parseToImage(arrayBuffer, options, url);
22
- break;
23
- case 'data':
24
- image = await parseToNodeImage(arrayBuffer, options);
25
- break;
26
- default:
27
- assert(false);
28
- }
29
- if (imageType === 'data') {
30
- image = getImageData(image);
31
- }
32
- return image;
10
+ options = options || {};
11
+ const imageOptions = options.image || {};
12
+ // The user can request a specific output format via `options.image.type`
13
+ const imageType = imageOptions.type || 'auto';
14
+ const { url } = context || {};
15
+ // Note: For options.image.type === `data`, we may still need to load as `image` or `imagebitmap`
16
+ const loadType = getLoadableImageType(imageType);
17
+ let image;
18
+ switch (loadType) {
19
+ case 'imagebitmap':
20
+ image = await parseToImageBitmap(arrayBuffer, options, url);
21
+ break;
22
+ case 'image':
23
+ image = await parseToImage(arrayBuffer, options, url);
24
+ break;
25
+ case 'data':
26
+ // Node.js loads imagedata directly
27
+ image = await parseToNodeImage(arrayBuffer, options);
28
+ break;
29
+ default:
30
+ assert(false);
31
+ }
32
+ // Browser: if options.image.type === 'data', we can now extract data from the loaded image
33
+ if (imageType === 'data') {
34
+ image = getImageData(image);
35
+ }
36
+ return image;
33
37
  }
38
+ // Get a loadable image type from image type
34
39
  function getLoadableImageType(type) {
35
- switch (type) {
36
- case 'auto':
37
- case 'data':
38
- return getDefaultImageType();
39
- default:
40
- isImageTypeSupported(type);
41
- return type;
42
- }
40
+ switch (type) {
41
+ case 'auto':
42
+ case 'data':
43
+ // Browser: For image data we need still need to load using an image format
44
+ // Node: the default image type is `data`.
45
+ return getDefaultImageType();
46
+ default:
47
+ // Throw an error if not supported
48
+ isImageTypeSupported(type);
49
+ return type;
50
+ }
43
51
  }
44
- //# sourceMappingURL=parse-image.js.map
@@ -1,4 +1,4 @@
1
- import type { ImageLoaderOptions } from '../../image-loader';
1
+ import type { ImageLoaderOptions } from "../../image-loader.js";
2
2
  /**
3
3
  * Asynchronously parses an array buffer into an ImageBitmap - this contains the decoded data
4
4
  * ImageBitmaps are supported on worker threads, but not supported on Edge, IE11 and Safari
@@ -1 +1 @@
1
- {"version":3,"file":"parse-to-image-bitmap.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-to-image-bitmap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAQ3D;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,kBAAkB,EAC3B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,CAgBtB"}
1
+ {"version":3,"file":"parse-to-image-bitmap.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/parse-to-image-bitmap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,8BAA2B;AAQ3D;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,kBAAkB,EAC3B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,CAgBtB"}