@loaders.gl/textures 4.2.0-alpha.4 → 4.2.0-alpha.5

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 (103) hide show
  1. package/dist/basis-loader.js +27 -19
  2. package/dist/compressed-texture-loader.js +51 -31
  3. package/dist/compressed-texture-writer.js +32 -19
  4. package/dist/crunch-loader.js +19 -13
  5. package/dist/dist.dev.js +326 -212
  6. package/dist/dist.min.js +10 -0
  7. package/dist/index.cjs +41 -60
  8. package/dist/index.cjs.map +7 -0
  9. package/dist/index.d.ts +16 -16
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +21 -13
  12. package/dist/ktx2-basis-writer.js +21 -15
  13. package/dist/lib/encoders/encode-ktx.js +6 -3
  14. package/dist/lib/encoders/encode-ktx2-basis-texture.js +38 -33
  15. package/dist/lib/encoders/encode-texture.d.ts +1 -1
  16. package/dist/lib/encoders/encode-texture.d.ts.map +1 -1
  17. package/dist/lib/encoders/encode-texture.js +23 -9
  18. package/dist/lib/gl-extensions.js +70 -59
  19. package/dist/lib/parsers/basis-module-loader.js +97 -61
  20. package/dist/lib/parsers/crunch-module-loader.js +29 -13
  21. package/dist/lib/parsers/parse-basis.js +217 -205
  22. package/dist/lib/parsers/parse-compressed-texture.js +20 -11
  23. package/dist/lib/parsers/parse-crunch.js +89 -59
  24. package/dist/lib/parsers/parse-dds.js +82 -53
  25. package/dist/lib/parsers/parse-ktx.js +37 -18
  26. package/dist/lib/parsers/parse-npy.js +70 -53
  27. package/dist/lib/parsers/parse-pvr.js +203 -112
  28. package/dist/lib/texture-api/async-deep-map.js +33 -28
  29. package/dist/lib/texture-api/deep-load.js +7 -5
  30. package/dist/lib/texture-api/generate-url.d.ts +1 -1
  31. package/dist/lib/texture-api/generate-url.d.ts.map +1 -1
  32. package/dist/lib/texture-api/generate-url.js +12 -10
  33. package/dist/lib/texture-api/load-image-array.d.ts +1 -1
  34. package/dist/lib/texture-api/load-image-array.d.ts.map +1 -1
  35. package/dist/lib/texture-api/load-image-array.js +13 -15
  36. package/dist/lib/texture-api/load-image-cube.d.ts +1 -1
  37. package/dist/lib/texture-api/load-image-cube.d.ts.map +1 -1
  38. package/dist/lib/texture-api/load-image-cube.js +32 -51
  39. package/dist/lib/texture-api/load-image.d.ts +1 -1
  40. package/dist/lib/texture-api/load-image.d.ts.map +1 -1
  41. package/dist/lib/texture-api/load-image.js +30 -36
  42. package/dist/lib/texture-api/texture-api-types.js +3 -1
  43. package/dist/lib/utils/extract-mipmap-images.js +43 -29
  44. package/dist/lib/utils/ktx-format-helper.js +119 -68
  45. package/dist/lib/utils/texture-formats.js +40 -26
  46. package/dist/lib/utils/version.js +6 -1
  47. package/dist/npy-loader.d.ts +1 -1
  48. package/dist/npy-loader.d.ts.map +1 -1
  49. package/dist/npy-loader.js +24 -15
  50. package/dist/workers/basis-worker-node.js +4 -1
  51. package/dist/workers/basis-worker.js +3 -1
  52. package/dist/workers/compressed-texture-worker.js +4 -1
  53. package/dist/workers/crunch-worker.d.ts +1 -1
  54. package/dist/workers/crunch-worker.d.ts.map +1 -1
  55. package/dist/workers/crunch-worker.js +8 -3
  56. package/dist/workers/ktx2-basis-writer-worker-node.js +23 -26
  57. package/dist/workers/ktx2-basis-writer-worker.js +22 -26
  58. package/dist/workers/npy-worker.js +3 -1
  59. package/package.json +13 -9
  60. package/dist/basis-loader.js.map +0 -1
  61. package/dist/compressed-texture-loader.js.map +0 -1
  62. package/dist/compressed-texture-writer.js.map +0 -1
  63. package/dist/crunch-loader.js.map +0 -1
  64. package/dist/index.js.map +0 -1
  65. package/dist/ktx2-basis-writer.js.map +0 -1
  66. package/dist/lib/encoders/encode-ktx.js.map +0 -1
  67. package/dist/lib/encoders/encode-ktx2-basis-texture.js.map +0 -1
  68. package/dist/lib/encoders/encode-texture.js.map +0 -1
  69. package/dist/lib/gl-extensions.js.map +0 -1
  70. package/dist/lib/parsers/basis-module-loader.js.map +0 -1
  71. package/dist/lib/parsers/crunch-module-loader.js.map +0 -1
  72. package/dist/lib/parsers/parse-basis.js.map +0 -1
  73. package/dist/lib/parsers/parse-compressed-texture.js.map +0 -1
  74. package/dist/lib/parsers/parse-crunch.js.map +0 -1
  75. package/dist/lib/parsers/parse-dds.js.map +0 -1
  76. package/dist/lib/parsers/parse-ktx.js.map +0 -1
  77. package/dist/lib/parsers/parse-npy.js.map +0 -1
  78. package/dist/lib/parsers/parse-pvr.js.map +0 -1
  79. package/dist/lib/texture-api/async-deep-map.js.map +0 -1
  80. package/dist/lib/texture-api/deep-load.js.map +0 -1
  81. package/dist/lib/texture-api/generate-url.js.map +0 -1
  82. package/dist/lib/texture-api/load-image-array.js.map +0 -1
  83. package/dist/lib/texture-api/load-image-cube.js.map +0 -1
  84. package/dist/lib/texture-api/load-image.js.map +0 -1
  85. package/dist/lib/texture-api/texture-api-types.js.map +0 -1
  86. package/dist/lib/utils/extract-mipmap-images.js.map +0 -1
  87. package/dist/lib/utils/ktx-format-helper.js.map +0 -1
  88. package/dist/lib/utils/texture-formats.js.map +0 -1
  89. package/dist/lib/utils/version.js.map +0 -1
  90. package/dist/libs/libs/README.md +0 -9
  91. package/dist/libs/libs/basis_encoder.js +0 -21
  92. package/dist/libs/libs/basis_encoder.wasm +0 -0
  93. package/dist/libs/libs/basis_transcoder.js +0 -22
  94. package/dist/libs/libs/basis_transcoder.wasm +0 -0
  95. package/dist/libs/libs/crunch.js +0 -136
  96. package/dist/npy-loader.js.map +0 -1
  97. package/dist/workers/basis-worker-node.js.map +0 -1
  98. package/dist/workers/basis-worker.js.map +0 -1
  99. package/dist/workers/compressed-texture-worker.js.map +0 -1
  100. package/dist/workers/crunch-worker.js.map +0 -1
  101. package/dist/workers/ktx2-basis-writer-worker-node.js.map +0 -1
  102. package/dist/workers/ktx2-basis-writer-worker.js.map +0 -1
  103. package/dist/workers/npy-worker.js.map +0 -1
@@ -1,231 +1,243 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
1
4
  import { loadBasisEncoderModule, loadBasisTranscoderModule } from "./basis-module-loader.js";
2
5
  import { GL_EXTENSIONS_CONSTANTS } from "../gl-extensions.js";
3
6
  import { getSupportedGPUTextureFormats } from "../utils/texture-formats.js";
4
7
  import { isKTX } from "./parse-ktx.js";
5
8
  const OutputFormat = {
6
- etc1: {
7
- basisFormat: 0,
8
- compressed: true,
9
- format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ETC1_WEBGL
10
- },
11
- etc2: {
12
- basisFormat: 1,
13
- compressed: true
14
- },
15
- bc1: {
16
- basisFormat: 2,
17
- compressed: true,
18
- format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT
19
- },
20
- bc3: {
21
- basisFormat: 3,
22
- compressed: true,
23
- format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT
24
- },
25
- bc4: {
26
- basisFormat: 4,
27
- compressed: true
28
- },
29
- bc5: {
30
- basisFormat: 5,
31
- compressed: true
32
- },
33
- 'bc7-m6-opaque-only': {
34
- basisFormat: 6,
35
- compressed: true
36
- },
37
- 'bc7-m5': {
38
- basisFormat: 7,
39
- compressed: true
40
- },
41
- 'pvrtc1-4-rgb': {
42
- basisFormat: 8,
43
- compressed: true,
44
- format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_4BPPV1_IMG
45
- },
46
- 'pvrtc1-4-rgba': {
47
- basisFormat: 9,
48
- compressed: true,
49
- format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
50
- },
51
- 'astc-4x4': {
52
- basisFormat: 10,
53
- compressed: true,
54
- format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4X4_KHR
55
- },
56
- 'atc-rgb': {
57
- basisFormat: 11,
58
- compressed: true
59
- },
60
- 'atc-rgba-interpolated-alpha': {
61
- basisFormat: 12,
62
- compressed: true
63
- },
64
- rgba32: {
65
- basisFormat: 13,
66
- compressed: false
67
- },
68
- rgb565: {
69
- basisFormat: 14,
70
- compressed: false
71
- },
72
- bgr565: {
73
- basisFormat: 15,
74
- compressed: false
75
- },
76
- rgba4444: {
77
- basisFormat: 16,
78
- compressed: false
79
- }
9
+ etc1: {
10
+ basisFormat: 0,
11
+ compressed: true,
12
+ format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ETC1_WEBGL
13
+ },
14
+ etc2: { basisFormat: 1, compressed: true },
15
+ bc1: {
16
+ basisFormat: 2,
17
+ compressed: true,
18
+ format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT
19
+ },
20
+ bc3: {
21
+ basisFormat: 3,
22
+ compressed: true,
23
+ format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT
24
+ },
25
+ bc4: { basisFormat: 4, compressed: true },
26
+ bc5: { basisFormat: 5, compressed: true },
27
+ 'bc7-m6-opaque-only': { basisFormat: 6, compressed: true },
28
+ 'bc7-m5': { basisFormat: 7, compressed: true },
29
+ 'pvrtc1-4-rgb': {
30
+ basisFormat: 8,
31
+ compressed: true,
32
+ format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_4BPPV1_IMG
33
+ },
34
+ 'pvrtc1-4-rgba': {
35
+ basisFormat: 9,
36
+ compressed: true,
37
+ format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
38
+ },
39
+ 'astc-4x4': {
40
+ basisFormat: 10,
41
+ compressed: true,
42
+ format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4X4_KHR
43
+ },
44
+ 'atc-rgb': { basisFormat: 11, compressed: true },
45
+ 'atc-rgba-interpolated-alpha': { basisFormat: 12, compressed: true },
46
+ rgba32: { basisFormat: 13, compressed: false },
47
+ rgb565: { basisFormat: 14, compressed: false },
48
+ bgr565: { basisFormat: 15, compressed: false },
49
+ rgba4444: { basisFormat: 16, compressed: false }
80
50
  };
51
+ /**
52
+ * parse data with a Binomial Basis_Universal module
53
+ * @param data
54
+ * @param options
55
+ * @returns compressed texture data
56
+ */
81
57
  export default async function parseBasis(data, options) {
82
- if (options.basis.containerFormat === 'auto') {
83
- if (isKTX(data)) {
84
- const fileConstructors = await loadBasisEncoderModule(options);
85
- return parseKTX2File(fileConstructors.KTX2File, data, options);
58
+ if (options.basis.containerFormat === 'auto') {
59
+ if (isKTX(data)) {
60
+ const fileConstructors = await loadBasisEncoderModule(options);
61
+ return parseKTX2File(fileConstructors.KTX2File, data, options);
62
+ }
63
+ const { BasisFile } = await loadBasisTranscoderModule(options);
64
+ return parseBasisFile(BasisFile, data, options);
86
65
  }
87
- const {
88
- BasisFile
89
- } = await loadBasisTranscoderModule(options);
90
- return parseBasisFile(BasisFile, data, options);
91
- }
92
- switch (options.basis.module) {
93
- case 'encoder':
94
- const fileConstructors = await loadBasisEncoderModule(options);
95
- switch (options.basis.containerFormat) {
96
- case 'ktx2':
97
- return parseKTX2File(fileConstructors.KTX2File, data, options);
98
- case 'basis':
66
+ switch (options.basis.module) {
67
+ case 'encoder':
68
+ const fileConstructors = await loadBasisEncoderModule(options);
69
+ switch (options.basis.containerFormat) {
70
+ case 'ktx2':
71
+ return parseKTX2File(fileConstructors.KTX2File, data, options);
72
+ case 'basis':
73
+ default:
74
+ return parseBasisFile(fileConstructors.BasisFile, data, options);
75
+ }
76
+ case 'transcoder':
99
77
  default:
100
- return parseBasisFile(fileConstructors.BasisFile, data, options);
101
- }
102
- case 'transcoder':
103
- default:
104
- const {
105
- BasisFile
106
- } = await loadBasisTranscoderModule(options);
107
- return parseBasisFile(BasisFile, data, options);
108
- }
78
+ const { BasisFile } = await loadBasisTranscoderModule(options);
79
+ return parseBasisFile(BasisFile, data, options);
80
+ }
109
81
  }
82
+ /**
83
+ * Parse *.basis file data
84
+ * @param BasisFile - initialized transcoder module
85
+ * @param data
86
+ * @param options
87
+ * @returns compressed texture data
88
+ */
110
89
  function parseBasisFile(BasisFile, data, options) {
111
- const basisFile = new BasisFile(new Uint8Array(data));
112
- try {
113
- if (!basisFile.startTranscoding()) {
114
- throw new Error('Failed to start basis transcoding');
90
+ const basisFile = new BasisFile(new Uint8Array(data));
91
+ try {
92
+ if (!basisFile.startTranscoding()) {
93
+ throw new Error('Failed to start basis transcoding');
94
+ }
95
+ const imageCount = basisFile.getNumImages();
96
+ const images = [];
97
+ for (let imageIndex = 0; imageIndex < imageCount; imageIndex++) {
98
+ const levelsCount = basisFile.getNumLevels(imageIndex);
99
+ const levels = [];
100
+ for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) {
101
+ levels.push(transcodeImage(basisFile, imageIndex, levelIndex, options));
102
+ }
103
+ images.push(levels);
104
+ }
105
+ return images;
115
106
  }
116
- const imageCount = basisFile.getNumImages();
117
- const images = [];
118
- for (let imageIndex = 0; imageIndex < imageCount; imageIndex++) {
119
- const levelsCount = basisFile.getNumLevels(imageIndex);
120
- const levels = [];
121
- for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) {
122
- levels.push(transcodeImage(basisFile, imageIndex, levelIndex, options));
123
- }
124
- images.push(levels);
107
+ finally {
108
+ basisFile.close();
109
+ basisFile.delete();
125
110
  }
126
- return images;
127
- } finally {
128
- basisFile.close();
129
- basisFile.delete();
130
- }
131
111
  }
112
+ /**
113
+ * Parse the particular level image of a basis file
114
+ * @param basisFile
115
+ * @param imageIndex
116
+ * @param levelIndex
117
+ * @param options
118
+ * @returns compressed texture data
119
+ */
132
120
  function transcodeImage(basisFile, imageIndex, levelIndex, options) {
133
- const width = basisFile.getImageWidth(imageIndex, levelIndex);
134
- const height = basisFile.getImageHeight(imageIndex, levelIndex);
135
- const hasAlpha = basisFile.getHasAlpha();
136
- const {
137
- compressed,
138
- format,
139
- basisFormat
140
- } = getBasisOptions(options, hasAlpha);
141
- const decodedSize = basisFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, basisFormat);
142
- const decodedData = new Uint8Array(decodedSize);
143
- if (!basisFile.transcodeImage(decodedData, imageIndex, levelIndex, basisFormat, 0, 0)) {
144
- throw new Error('failed to start Basis transcoding');
145
- }
146
- return {
147
- width,
148
- height,
149
- data: decodedData,
150
- compressed,
151
- format,
152
- hasAlpha
153
- };
121
+ const width = basisFile.getImageWidth(imageIndex, levelIndex);
122
+ const height = basisFile.getImageHeight(imageIndex, levelIndex);
123
+ // See https://github.com/BinomialLLC/basis_universal/pull/83
124
+ const hasAlpha = basisFile.getHasAlpha( /* imageIndex, levelIndex */);
125
+ // Check options for output format etc
126
+ const { compressed, format, basisFormat } = getBasisOptions(options, hasAlpha);
127
+ const decodedSize = basisFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, basisFormat);
128
+ const decodedData = new Uint8Array(decodedSize);
129
+ if (!basisFile.transcodeImage(decodedData, imageIndex, levelIndex, basisFormat, 0, 0)) {
130
+ throw new Error('failed to start Basis transcoding');
131
+ }
132
+ return {
133
+ // standard loaders.gl image category payload
134
+ width,
135
+ height,
136
+ data: decodedData,
137
+ compressed,
138
+ format,
139
+ // Additional fields
140
+ // Add levelSize field.
141
+ hasAlpha
142
+ };
154
143
  }
144
+ /**
145
+ * Parse *.ktx2 file data
146
+ * @param KTX2File
147
+ * @param data
148
+ * @param options
149
+ * @returns compressed texture data
150
+ */
155
151
  function parseKTX2File(KTX2File, data, options) {
156
- const ktx2File = new KTX2File(new Uint8Array(data));
157
- try {
158
- if (!ktx2File.startTranscoding()) {
159
- throw new Error('failed to start KTX2 transcoding');
152
+ const ktx2File = new KTX2File(new Uint8Array(data));
153
+ try {
154
+ if (!ktx2File.startTranscoding()) {
155
+ throw new Error('failed to start KTX2 transcoding');
156
+ }
157
+ const levelsCount = ktx2File.getLevels();
158
+ const levels = [];
159
+ for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) {
160
+ levels.push(transcodeKTX2Image(ktx2File, levelIndex, options));
161
+ break; // texture app can only show one level for some reason
162
+ }
163
+ return [levels];
160
164
  }
161
- const levelsCount = ktx2File.getLevels();
162
- const levels = [];
163
- for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) {
164
- levels.push(transcodeKTX2Image(ktx2File, levelIndex, options));
165
- break;
165
+ finally {
166
+ ktx2File.close();
167
+ ktx2File.delete();
166
168
  }
167
- return [levels];
168
- } finally {
169
- ktx2File.close();
170
- ktx2File.delete();
171
- }
172
169
  }
170
+ /**
171
+ * Parse the particular level image of a ktx2 file
172
+ * @param ktx2File
173
+ * @param levelIndex
174
+ * @param options
175
+ * @returns
176
+ */
173
177
  function transcodeKTX2Image(ktx2File, levelIndex, options) {
174
- const {
175
- alphaFlag,
176
- height,
177
- width
178
- } = ktx2File.getImageLevelInfo(levelIndex, 0, 0);
179
- const {
180
- compressed,
181
- format,
182
- basisFormat
183
- } = getBasisOptions(options, alphaFlag);
184
- const decodedSize = ktx2File.getImageTranscodedSizeInBytes(levelIndex, 0, 0, basisFormat);
185
- const decodedData = new Uint8Array(decodedSize);
186
- if (!ktx2File.transcodeImage(decodedData, levelIndex, 0, 0, basisFormat, 0, -1, -1)) {
187
- throw new Error('Failed to transcode KTX2 image');
188
- }
189
- return {
190
- width,
191
- height,
192
- data: decodedData,
193
- compressed,
194
- levelSize: decodedSize,
195
- hasAlpha: alphaFlag,
196
- format
197
- };
178
+ const { alphaFlag, height, width } = ktx2File.getImageLevelInfo(levelIndex, 0, 0);
179
+ // Check options for output format etc
180
+ const { compressed, format, basisFormat } = getBasisOptions(options, alphaFlag);
181
+ const decodedSize = ktx2File.getImageTranscodedSizeInBytes(levelIndex, 0 /* layerIndex */, 0 /* faceIndex */, basisFormat);
182
+ const decodedData = new Uint8Array(decodedSize);
183
+ if (!ktx2File.transcodeImage(decodedData, levelIndex, 0 /* layerIndex */, 0 /* faceIndex */, basisFormat, 0, -1 /* channel0 */, -1 /* channel1 */)) {
184
+ throw new Error('Failed to transcode KTX2 image');
185
+ }
186
+ return {
187
+ // standard loaders.gl image category payload
188
+ width,
189
+ height,
190
+ data: decodedData,
191
+ compressed,
192
+ // Additional fields
193
+ levelSize: decodedSize,
194
+ hasAlpha: alphaFlag,
195
+ format
196
+ };
198
197
  }
198
+ /**
199
+ * Get BasisFormat by loader format option
200
+ * @param options
201
+ * @param hasAlpha
202
+ * @returns BasisFormat data
203
+ */
199
204
  function getBasisOptions(options, hasAlpha) {
200
- let format = options && options.basis && options.basis.format;
201
- if (format === 'auto') {
202
- format = selectSupportedBasisFormat();
203
- }
204
- if (typeof format === 'object') {
205
- format = hasAlpha ? format.alpha : format.noAlpha;
206
- }
207
- format = format.toLowerCase();
208
- return OutputFormat[format];
205
+ let format = options && options.basis && options.basis.format;
206
+ if (format === 'auto') {
207
+ format = selectSupportedBasisFormat();
208
+ }
209
+ if (typeof format === 'object') {
210
+ format = hasAlpha ? format.alpha : format.noAlpha;
211
+ }
212
+ format = format.toLowerCase();
213
+ return OutputFormat[format];
209
214
  }
215
+ /**
216
+ * Select transcode format from the list of supported formats
217
+ * @returns key for OutputFormat map
218
+ */
210
219
  export function selectSupportedBasisFormat() {
211
- const supportedFormats = getSupportedGPUTextureFormats();
212
- if (supportedFormats.has('astc')) {
213
- return 'astc-4x4';
214
- } else if (supportedFormats.has('dxt')) {
215
- return {
216
- alpha: 'bc3',
217
- noAlpha: 'bc1'
218
- };
219
- } else if (supportedFormats.has('pvrtc')) {
220
- return {
221
- alpha: 'pvrtc1-4-rgba',
222
- noAlpha: 'pvrtc1-4-rgb'
223
- };
224
- } else if (supportedFormats.has('etc1')) {
225
- return 'etc1';
226
- } else if (supportedFormats.has('etc2')) {
227
- return 'etc2';
228
- }
229
- return 'rgb565';
220
+ const supportedFormats = getSupportedGPUTextureFormats();
221
+ if (supportedFormats.has('astc')) {
222
+ return 'astc-4x4';
223
+ }
224
+ else if (supportedFormats.has('dxt')) {
225
+ return {
226
+ alpha: 'bc3',
227
+ noAlpha: 'bc1'
228
+ };
229
+ }
230
+ else if (supportedFormats.has('pvrtc')) {
231
+ return {
232
+ alpha: 'pvrtc1-4-rgba',
233
+ noAlpha: 'pvrtc1-4-rgb'
234
+ };
235
+ }
236
+ else if (supportedFormats.has('etc1')) {
237
+ return 'etc1';
238
+ }
239
+ else if (supportedFormats.has('etc2')) {
240
+ return 'etc2';
241
+ }
242
+ return 'rgb565';
230
243
  }
231
- //# sourceMappingURL=parse-basis.js.map
@@ -1,16 +1,25 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
1
4
  import { isKTX, parseKTX } from "./parse-ktx.js";
2
5
  import { isDDS, parseDDS } from "./parse-dds.js";
3
6
  import { isPVR, parsePVR } from "./parse-pvr.js";
7
+ /**
8
+ * Deduces format and parses compressed texture loaded in ArrayBuffer
9
+ * @param data - binary data of compressed texture
10
+ * @returns Array of the texture levels
11
+ */
4
12
  export function parseCompressedTexture(data) {
5
- if (isKTX(data)) {
6
- return parseKTX(data);
7
- }
8
- if (isDDS(data)) {
9
- return parseDDS(data);
10
- }
11
- if (isPVR(data)) {
12
- return parsePVR(data);
13
- }
14
- throw new Error('Texture container format not recognized');
13
+ if (isKTX(data)) {
14
+ // TODO: remove @ts-ignore when `parseKTX` output is normalized to loaders.gl texture format
15
+ // @ts-ignore
16
+ return parseKTX(data);
17
+ }
18
+ if (isDDS(data)) {
19
+ return parseDDS(data);
20
+ }
21
+ if (isPVR(data)) {
22
+ return parsePVR(data);
23
+ }
24
+ throw new Error('Texture container format not recognized');
15
25
  }
16
- //# sourceMappingURL=parse-compressed-texture.js.map
@@ -1,75 +1,105 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
1
4
  import { loadCrunchModule } from "./crunch-module-loader.js";
2
5
  import { GL_EXTENSIONS_CONSTANTS } from "../gl-extensions.js";
3
6
  import { assert } from '@loaders.gl/loader-utils';
4
7
  import { getDxt1LevelSize, getDxtXLevelSize } from "./parse-dds.js";
5
8
  import { extractMipmapImages } from "../utils/extract-mipmap-images.js";
9
+ // Taken from crnlib.h
6
10
  const CRN_FORMAT = {
7
- cCRNFmtInvalid: -1,
8
- cCRNFmtDXT1: 0,
9
- cCRNFmtDXT3: 1,
10
- cCRNFmtDXT5: 2
11
+ cCRNFmtInvalid: -1,
12
+ cCRNFmtDXT1: 0,
13
+ // cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS.
14
+ cCRNFmtDXT3: 1,
15
+ cCRNFmtDXT5: 2
16
+ // Crunch supports more formats than this.
11
17
  };
18
+ /** Mapping of Crunch formats to DXT formats. */
12
19
  const DXT_FORMAT_MAP = {
13
- [CRN_FORMAT.cCRNFmtDXT1]: {
14
- pixelFormat: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT,
15
- sizeFunction: getDxt1LevelSize
16
- },
17
- [CRN_FORMAT.cCRNFmtDXT3]: {
18
- pixelFormat: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT3_EXT,
19
- sizeFunction: getDxtXLevelSize
20
- },
21
- [CRN_FORMAT.cCRNFmtDXT5]: {
22
- pixelFormat: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT,
23
- sizeFunction: getDxtXLevelSize
24
- }
20
+ [CRN_FORMAT.cCRNFmtDXT1]: {
21
+ pixelFormat: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT,
22
+ sizeFunction: getDxt1LevelSize
23
+ },
24
+ [CRN_FORMAT.cCRNFmtDXT3]: {
25
+ pixelFormat: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT3_EXT,
26
+ sizeFunction: getDxtXLevelSize
27
+ },
28
+ [CRN_FORMAT.cCRNFmtDXT5]: {
29
+ pixelFormat: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT,
30
+ sizeFunction: getDxtXLevelSize
31
+ }
25
32
  };
26
33
  let cachedDstSize = 0;
27
34
  let dst;
35
+ /**
36
+ * Parse texture data as "CRN" format.
37
+ * Function is "async" as emscriptified decoder module is loaded asyncronously
38
+ * @param data - binary data of compressed texture
39
+ * @returns Promise of Array of the texture levels
40
+ */
28
41
  export async function parseCrunch(data, options) {
29
- const crunchModule = await loadCrunchModule(options);
30
- const srcSize = data.byteLength;
31
- const bytes = new Uint8Array(data);
32
- const src = crunchModule._malloc(srcSize);
33
- arrayBufferCopy(bytes, crunchModule.HEAPU8, src, srcSize);
34
- const format = crunchModule._crn_get_dxt_format(src, srcSize);
35
- assert(Boolean(DXT_FORMAT_MAP[format]), 'Unsupported format');
36
- const mipMapLevels = crunchModule._crn_get_levels(src, srcSize);
37
- const width = crunchModule._crn_get_width(src, srcSize);
38
- const height = crunchModule._crn_get_height(src, srcSize);
39
- const sizeFunction = DXT_FORMAT_MAP[format].sizeFunction;
40
- let dstSize = 0;
41
- for (let i = 0; i < mipMapLevels; ++i) {
42
- dstSize += sizeFunction(width >> i, height >> i);
43
- }
44
- if (cachedDstSize < dstSize) {
45
- if (dst) {
46
- crunchModule._free(dst);
42
+ const crunchModule = await loadCrunchModule(options);
43
+ // Copy the contents of the arrayBuffer into emscriptens heap.
44
+ const srcSize = data.byteLength;
45
+ const bytes = new Uint8Array(data);
46
+ const src = crunchModule._malloc(srcSize);
47
+ arrayBufferCopy(bytes, crunchModule.HEAPU8, src, srcSize);
48
+ // Determine what type of compressed data the file contains.
49
+ const format = crunchModule._crn_get_dxt_format(src, srcSize);
50
+ assert(Boolean(DXT_FORMAT_MAP[format]), 'Unsupported format');
51
+ // Gather basic metrics about the DXT data.
52
+ const mipMapLevels = crunchModule._crn_get_levels(src, srcSize);
53
+ const width = crunchModule._crn_get_width(src, srcSize);
54
+ const height = crunchModule._crn_get_height(src, srcSize);
55
+ // const bytesPerBlock = crunchModule._crn_get_bytes_per_block(src, srcSize);
56
+ // Determine the size of the decoded DXT data.
57
+ const sizeFunction = DXT_FORMAT_MAP[format].sizeFunction;
58
+ let dstSize = 0;
59
+ for (let i = 0; i < mipMapLevels; ++i) {
60
+ dstSize += sizeFunction(width >> i, height >> i);
61
+ }
62
+ // Allocate enough space on the emscripten heap to hold the decoded DXT data
63
+ // or reuse the existing allocation if a previous call to this function has
64
+ // already acquired a large enough buffer.
65
+ if (cachedDstSize < dstSize) {
66
+ if (dst) {
67
+ crunchModule._free(dst);
68
+ }
69
+ dst = crunchModule._malloc(dstSize);
70
+ cachedDstSize = dstSize;
47
71
  }
48
- dst = crunchModule._malloc(dstSize);
49
- cachedDstSize = dstSize;
50
- }
51
- crunchModule._crn_decompress(src, srcSize, dst, dstSize, 0, mipMapLevels);
52
- crunchModule._free(src);
53
- const image = new Uint8Array(crunchModule.HEAPU8.buffer, dst, dstSize).slice();
54
- return extractMipmapImages(image, {
55
- mipMapLevels,
56
- width,
57
- height,
58
- sizeFunction,
59
- internalFormat: DXT_FORMAT_MAP[format].pixelFormat
60
- });
72
+ // Decompress the DXT data from the Crunch file into the allocated space.
73
+ crunchModule._crn_decompress(src, srcSize, dst, dstSize, 0, mipMapLevels);
74
+ // Release the crunch file data from the emscripten heap.
75
+ crunchModule._free(src);
76
+ const image = new Uint8Array(crunchModule.HEAPU8.buffer, dst, dstSize).slice();
77
+ return extractMipmapImages(image, {
78
+ mipMapLevels,
79
+ width,
80
+ height,
81
+ sizeFunction,
82
+ internalFormat: DXT_FORMAT_MAP[format].pixelFormat
83
+ });
61
84
  }
85
+ /**
86
+ * Copy an array of bytes into or out of the emscripten heap
87
+ * @param {Uint8Array} srcData - Source data array
88
+ * @param {Uint8Array} dstData - Destination data array
89
+ * @param {number} dstByteOffset - Destination data offset
90
+ * @param {number} numBytes - number of bytes to copy
91
+ * @returns {void}
92
+ */
62
93
  function arrayBufferCopy(srcData, dstData, dstByteOffset, numBytes) {
63
- let i;
64
- const dst32Offset = dstByteOffset / 4;
65
- const tail = numBytes % 4;
66
- const src32 = new Uint32Array(srcData.buffer, 0, (numBytes - tail) / 4);
67
- const dst32 = new Uint32Array(dstData.buffer);
68
- for (i = 0; i < src32.length; i++) {
69
- dst32[dst32Offset + i] = src32[i];
70
- }
71
- for (i = numBytes - tail; i < numBytes; i++) {
72
- dstData[dstByteOffset + i] = srcData[i];
73
- }
94
+ let i;
95
+ const dst32Offset = dstByteOffset / 4;
96
+ const tail = numBytes % 4;
97
+ const src32 = new Uint32Array(srcData.buffer, 0, (numBytes - tail) / 4);
98
+ const dst32 = new Uint32Array(dstData.buffer);
99
+ for (i = 0; i < src32.length; i++) {
100
+ dst32[dst32Offset + i] = src32[i];
101
+ }
102
+ for (i = numBytes - tail; i < numBytes; i++) {
103
+ dstData[dstByteOffset + i] = srcData[i];
104
+ }
74
105
  }
75
- //# sourceMappingURL=parse-crunch.js.map