@workglow/util 0.2.14 → 0.2.16

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 (42) hide show
  1. package/dist/browser.js +28 -18
  2. package/dist/browser.js.map +6 -5
  3. package/dist/bun.js +28 -18
  4. package/dist/bun.js.map +6 -5
  5. package/dist/logging/LoggerRegistry.d.ts.map +1 -1
  6. package/dist/media/Image.browser.d.ts +24 -0
  7. package/dist/media/Image.browser.d.ts.map +1 -0
  8. package/dist/media/Image.d.ts +100 -0
  9. package/dist/media/Image.d.ts.map +1 -0
  10. package/dist/media/MediaRawImage.d.ts +27 -0
  11. package/dist/media/MediaRawImage.d.ts.map +1 -0
  12. package/dist/media/color.d.ts +41 -0
  13. package/dist/media/color.d.ts.map +1 -0
  14. package/dist/media/imageRasterCodecRegistry.d.ts +13 -0
  15. package/dist/media/imageRasterCodecRegistry.d.ts.map +1 -0
  16. package/dist/media/{image.d.ts → imageTypes.d.ts} +5 -1
  17. package/dist/media/imageTypes.d.ts.map +1 -0
  18. package/dist/media-browser.d.ts +6 -2
  19. package/dist/media-browser.d.ts.map +1 -1
  20. package/dist/media-browser.js +521 -41
  21. package/dist/media-browser.js.map +9 -5
  22. package/dist/media-node.d.ts +5 -2
  23. package/dist/media-node.d.ts.map +1 -1
  24. package/dist/media-node.js +424 -23
  25. package/dist/media-node.js.map +8 -5
  26. package/dist/node.js +28 -18
  27. package/dist/node.js.map +6 -5
  28. package/dist/telemetry/TelemetryRegistry.d.ts.map +1 -1
  29. package/dist/utilities/runtimeEnv.d.ts +18 -0
  30. package/dist/utilities/runtimeEnv.d.ts.map +1 -0
  31. package/dist/worker-browser.js +26 -10
  32. package/dist/worker-browser.js.map +5 -4
  33. package/dist/worker-bun.js +26 -10
  34. package/dist/worker-bun.js.map +5 -4
  35. package/dist/worker-node.js +26 -10
  36. package/dist/worker-node.js.map +5 -4
  37. package/package.json +3 -3
  38. package/dist/media/image.browser.d.ts +0 -11
  39. package/dist/media/image.browser.d.ts.map +0 -1
  40. package/dist/media/image.d.ts.map +0 -1
  41. package/dist/media/image.node.d.ts +0 -11
  42. package/dist/media/image.node.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- // src/media/image.ts
1
+ // src/media/imageTypes.ts
2
2
  function parseDataUri(dataUri) {
3
3
  const match = dataUri.match(/^data:([^;]+);base64,(.+)$/);
4
4
  if (!match) {
@@ -9,65 +9,545 @@ function parseDataUri(dataUri) {
9
9
  base64: match[2]
10
10
  };
11
11
  }
12
- // src/media/image.browser.ts
13
- var convertBlobToOffscreenCanvas = async (blob) => {
14
- const img = await createImageBitmap(blob);
15
- const ctx = new OffscreenCanvas(img.width, img.height).getContext("2d");
16
- if (!ctx) {
17
- throw new Error("Failed to get context.");
12
+ // src/media/color.ts
13
+ var HEX_PATTERN = /^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
14
+ function parseHexColor(hex) {
15
+ if (typeof hex !== "string" || !HEX_PATTERN.test(hex)) {
16
+ throw new Error(`Invalid hex color: ${String(hex)}`);
18
17
  }
19
- ctx.drawImage(img, 0, 0);
20
- return ctx.canvas;
21
- };
18
+ const body = hex.slice(1);
19
+ const double = (nibble) => parseInt(nibble + nibble, 16);
20
+ if (body.length === 3) {
21
+ return { r: double(body[0]), g: double(body[1]), b: double(body[2]), a: 255 };
22
+ }
23
+ if (body.length === 4) {
24
+ return {
25
+ r: double(body[0]),
26
+ g: double(body[1]),
27
+ b: double(body[2]),
28
+ a: double(body[3])
29
+ };
30
+ }
31
+ if (body.length === 6) {
32
+ return {
33
+ r: parseInt(body.slice(0, 2), 16),
34
+ g: parseInt(body.slice(2, 4), 16),
35
+ b: parseInt(body.slice(4, 6), 16),
36
+ a: 255
37
+ };
38
+ }
39
+ return {
40
+ r: parseInt(body.slice(0, 2), 16),
41
+ g: parseInt(body.slice(2, 4), 16),
42
+ b: parseInt(body.slice(4, 6), 16),
43
+ a: parseInt(body.slice(6, 8), 16)
44
+ };
45
+ }
46
+ var CHANNEL_MIN = 0;
47
+ var CHANNEL_MAX = 255;
48
+ function assertChannel(name, value) {
49
+ if (!Number.isInteger(value) || value < CHANNEL_MIN || value > CHANNEL_MAX) {
50
+ throw new Error(`Color channel ${name} out of range (0-255 integer): ${value}`);
51
+ }
52
+ }
53
+ function byteToHex(value) {
54
+ return value.toString(16).padStart(2, "0");
55
+ }
56
+ function toHexColor(c) {
57
+ assertChannel("r", c.r);
58
+ assertChannel("g", c.g);
59
+ assertChannel("b", c.b);
60
+ assertChannel("a", c.a);
61
+ const head = `#${byteToHex(c.r)}${byteToHex(c.g)}${byteToHex(c.b)}`;
62
+ return c.a === 255 ? head : `${head}${byteToHex(c.a)}`;
63
+ }
64
+ function isInRangeByte(value) {
65
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 255;
66
+ }
67
+ function isColorObject(value) {
68
+ if (value === null || typeof value !== "object" || Array.isArray(value))
69
+ return false;
70
+ const candidate = value;
71
+ if (!isInRangeByte(candidate.r))
72
+ return false;
73
+ if (!isInRangeByte(candidate.g))
74
+ return false;
75
+ if (!isInRangeByte(candidate.b))
76
+ return false;
77
+ if (candidate.a !== undefined && !isInRangeByte(candidate.a))
78
+ return false;
79
+ return true;
80
+ }
81
+ function isHexColor(value) {
82
+ return typeof value === "string" && HEX_PATTERN.test(value);
83
+ }
84
+ function resolveColor(value) {
85
+ if (typeof value === "string")
86
+ return parseHexColor(value);
87
+ if (!isColorObject(value)) {
88
+ throw new Error(`Invalid color value: ${JSON.stringify(value)}`);
89
+ }
90
+ return {
91
+ r: value.r,
92
+ g: value.g,
93
+ b: value.b,
94
+ a: value.a ?? 255
95
+ };
96
+ }
97
+ // src/media/imageRasterCodecRegistry.ts
98
+ var codec = null;
99
+ function registerImageRasterCodec(next) {
100
+ codec = next;
101
+ }
102
+ function getImageRasterCodec() {
103
+ if (!codec) {
104
+ throw new Error("Image raster codec is not registered. Ensure you import @workglow/tasks from the browser or Node entry (dist/browser.js or dist/node.js), or call registerImageRasterCodec() during startup.");
105
+ }
106
+ return codec;
107
+ }
108
+ // src/media/MediaRawImage.ts
109
+ class MediaRawImage {
110
+ data;
111
+ width;
112
+ height;
113
+ channels;
114
+ constructor(data, width, height, channels) {
115
+ this.data = data;
116
+ this.width = width;
117
+ this.height = height;
118
+ this.channels = channels;
119
+ }
120
+ }
121
+ function isMediaRawImageShape(value) {
122
+ if (!value || typeof value !== "object")
123
+ return false;
124
+ const v = value;
125
+ return v.data instanceof Uint8ClampedArray && typeof v.width === "number" && typeof v.height === "number" && typeof v.channels === "number";
126
+ }
127
+ // src/media/Image.ts
128
+ var IMAGE_BRAND = Symbol.for("@workglow/util/media/Image");
129
+ function parseDataUriMimeType(dataUri) {
130
+ const match = dataUri.match(/^data:([^;,]+)/);
131
+ const raw = match?.[1]?.trim();
132
+ return raw ? raw.toLowerCase() : "image/png";
133
+ }
22
134
  function dataUriToBlob(dataUri) {
23
135
  const { mimeType, base64 } = parseDataUri(dataUri);
24
136
  const binary = atob(base64);
25
- const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
26
- const blob = new Blob([bytes], { type: mimeType });
27
- return blob;
137
+ const bytes = new Uint8Array(binary.length);
138
+ for (let i = 0;i < binary.length; i++) {
139
+ bytes[i] = binary.charCodeAt(i);
140
+ }
141
+ return new Blob([bytes], { type: mimeType });
142
+ }
143
+ function toImageBinary(value) {
144
+ const ch = value.channels;
145
+ if (ch !== 1 && ch !== 3 && ch !== 4) {
146
+ throw new Error(`Image: unsupported channel count ${ch}`);
147
+ }
148
+ const data = coerceToUint8ClampedArray(value.data);
149
+ return {
150
+ data,
151
+ width: value.width,
152
+ height: value.height,
153
+ channels: ch,
154
+ rawChannels: value.rawChannels
155
+ };
28
156
  }
29
- async function convertImageDataToUseableForm(imageData, supports) {
30
- if (imageData === null || imageData === undefined) {
31
- throw new Error("Image data is null or undefined");
157
+ function coerceToUint8ClampedArray(data) {
158
+ if (data instanceof Uint8ClampedArray) {
159
+ return data;
32
160
  }
33
- if (supports.includes("ImageBitmap") && imageData instanceof ImageBitmap) {
34
- return imageData;
161
+ if (ArrayBuffer.isView(data)) {
162
+ return new Uint8ClampedArray(data.buffer, data.byteOffset, data.byteLength);
35
163
  }
36
- if (supports.includes("VideoFrame") && imageData instanceof VideoFrame) {
37
- return imageData;
164
+ if (Array.isArray(data)) {
165
+ return Uint8ClampedArray.from(data);
38
166
  }
39
- if (supports.includes("Blob") && imageData instanceof Blob) {
40
- return imageData;
167
+ if (data && typeof data === "object") {
168
+ const obj = data;
169
+ const keys = Object.keys(obj);
170
+ if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
171
+ const arr = new Uint8ClampedArray(keys.length);
172
+ for (let i = 0;i < keys.length; i++) {
173
+ arr[i] = Number(obj[String(i)]);
174
+ }
175
+ return arr;
176
+ }
41
177
  }
42
- if (supports.includes("ImageBinary") && typeof imageData === "object" && "data" in imageData && "width" in imageData && "height" in imageData && "channels" in imageData) {
43
- return imageData;
178
+ throw new Error("Image: pixel data is not array-like");
179
+ }
180
+
181
+ class Image {
182
+ [IMAGE_BRAND] = true;
183
+ source;
184
+ pixelsCache;
185
+ dataUriCache = new Map;
186
+ blobCache = new Map;
187
+ constructor(source) {
188
+ this.source = source;
44
189
  }
45
- if (supports.includes("ImageBitmap") && imageData instanceof Blob) {
46
- return createImageBitmap(imageData);
190
+ static fromDataUri(dataUri) {
191
+ if (!dataUri.startsWith("data:")) {
192
+ throw new Error("Image.fromDataUri: input must start with 'data:'");
193
+ }
194
+ return new Image({ kind: "dataUri", dataUri, mimeType: parseDataUriMimeType(dataUri) });
47
195
  }
48
- if (supports.includes("OffscreenCanvas") && imageData instanceof Blob) {
49
- return await convertBlobToOffscreenCanvas(imageData);
196
+ static fromPixels(pixels) {
197
+ return new Image({ kind: "pixels", pixels });
50
198
  }
51
- if (supports.includes("ImageBitmap") && imageData instanceof OffscreenCanvas) {
52
- return imageData.transferToImageBitmap();
199
+ static fromBlob(blob) {
200
+ return new Image({ kind: "blob", blob });
53
201
  }
54
- if (supports.includes("ImageBitmap") && typeof imageData === "string") {
55
- return createImageBitmap(dataUriToBlob(imageData));
202
+ static from(value) {
203
+ if (Image.is(value)) {
204
+ return value;
205
+ }
206
+ if (typeof value === "string" && value.startsWith("data:")) {
207
+ return Image.fromDataUri(value);
208
+ }
209
+ if (typeof Blob !== "undefined" && value instanceof Blob) {
210
+ return Image.fromBlob(value);
211
+ }
212
+ if (typeof ImageBitmap !== "undefined" && value instanceof ImageBitmap) {
213
+ return new Image({ kind: "bitmap", bitmap: value });
214
+ }
215
+ if (typeof VideoFrame !== "undefined" && value instanceof VideoFrame) {
216
+ return new Image({ kind: "videoFrame", frame: value });
217
+ }
218
+ if (typeof OffscreenCanvas !== "undefined" && value instanceof OffscreenCanvas) {
219
+ return new Image({ kind: "offscreenCanvas", canvas: value });
220
+ }
221
+ if (value && typeof value === "object" && "data" in value && "width" in value && "height" in value && "channels" in value) {
222
+ return Image.fromPixels(toImageBinary(value));
223
+ }
224
+ throw new Error(`Image.from: unsupported image value of type ${typeof value}`);
56
225
  }
57
- if (supports.includes("OffscreenCanvas") && typeof imageData === "string") {
58
- return convertBlobToOffscreenCanvas(dataUriToBlob(imageData));
226
+ static is(value) {
227
+ return typeof value === "object" && value !== null && value[IMAGE_BRAND] === true;
59
228
  }
60
- if (supports.includes("Blob") && typeof imageData === "string") {
61
- return dataUriToBlob(imageData);
229
+ static fromJSON(value) {
230
+ if (Image.is(value)) {
231
+ return value;
232
+ }
233
+ if (typeof value === "string" && value.startsWith("data:")) {
234
+ return Image.fromDataUri(value);
235
+ }
236
+ if (value && typeof value === "object" && value.unsynced === true) {
237
+ const kind = value.kind;
238
+ throw new Error(`Image.fromJSON: cannot reconstruct image from "unsynced" sentinel (kind=${String(kind)}); pixels were not materialized before serialization. Call await image.getPixels() before JSON.stringify.`);
239
+ }
240
+ if (value && typeof value === "object" && "data" in value && typeof value.width === "number" && typeof value.height === "number" && typeof value.channels === "number") {
241
+ const v = value;
242
+ return Image.fromPixels(toImageBinary({
243
+ data: v.data,
244
+ width: v.width,
245
+ height: v.height,
246
+ channels: v.channels
247
+ }));
248
+ }
249
+ throw new Error("Image.fromJSON: value does not match any known Image shape");
62
250
  }
63
- if (supports.includes("DataUri") && typeof imageData === "string" && imageData.startsWith("data:")) {
64
- return imageData;
251
+ get kind() {
252
+ return this.source.kind;
65
253
  }
66
- throw new Error(`Unsupported image data type: ${typeof imageData} `);
254
+ get mimeType() {
255
+ if (this.source.kind === "dataUri")
256
+ return this.source.mimeType;
257
+ if (this.source.kind === "blob")
258
+ return this.source.blob.type || undefined;
259
+ return;
260
+ }
261
+ get width() {
262
+ if (this.source.kind === "pixels")
263
+ return this.source.pixels.width;
264
+ if (this.source.kind === "bitmap")
265
+ return this.source.bitmap.width;
266
+ if (this.source.kind === "offscreenCanvas")
267
+ return this.source.canvas.width;
268
+ if (this.source.kind === "videoFrame")
269
+ return this.source.frame.displayWidth;
270
+ return this.pixelsCache?.width;
271
+ }
272
+ get height() {
273
+ if (this.source.kind === "pixels")
274
+ return this.source.pixels.height;
275
+ if (this.source.kind === "bitmap")
276
+ return this.source.bitmap.height;
277
+ if (this.source.kind === "offscreenCanvas")
278
+ return this.source.canvas.height;
279
+ if (this.source.kind === "videoFrame")
280
+ return this.source.frame.displayHeight;
281
+ return this.pixelsCache?.height;
282
+ }
283
+ get channels() {
284
+ if (this.source.kind === "pixels")
285
+ return this.source.pixels.channels;
286
+ return this.pixelsCache?.channels;
287
+ }
288
+ async getPixels() {
289
+ if (this.pixelsCache)
290
+ return this.pixelsCache;
291
+ if (this.source.kind === "pixels") {
292
+ this.pixelsCache = this.source.pixels;
293
+ return this.pixelsCache;
294
+ }
295
+ if (this.source.kind === "dataUri") {
296
+ this.pixelsCache = await getImageRasterCodec().decodeDataUri(this.source.dataUri);
297
+ return this.pixelsCache;
298
+ }
299
+ if (this.source.kind === "blob") {
300
+ const dataUri = await blobToDataUri(this.source.blob);
301
+ this.pixelsCache = await getImageRasterCodec().decodeDataUri(dataUri);
302
+ return this.pixelsCache;
303
+ }
304
+ throw new Error(`Image.getPixels: browser-only source '${this.source.kind}' requires Image.browser augmentation`);
305
+ }
306
+ async getDataUri(mimeType = "image/png") {
307
+ if (this.source.kind === "dataUri") {
308
+ if (mimeType === this.source.mimeType) {
309
+ return this.source.dataUri;
310
+ }
311
+ }
312
+ const cached = this.dataUriCache.get(mimeType);
313
+ if (cached)
314
+ return cached;
315
+ const pixels = await this.getPixels();
316
+ const dataUri = await getImageRasterCodec().encodeDataUri(pixels, mimeType);
317
+ this.dataUriCache.set(mimeType, dataUri);
318
+ return dataUri;
319
+ }
320
+ async getBlob(mimeType = "image/png") {
321
+ if (this.source.kind === "blob" && (!mimeType || this.source.blob.type === mimeType)) {
322
+ return this.source.blob;
323
+ }
324
+ const cached = this.blobCache.get(mimeType);
325
+ if (cached)
326
+ return cached;
327
+ if (this.source.kind === "dataUri" && this.source.mimeType === mimeType) {
328
+ const blob2 = dataUriToBlob(this.source.dataUri);
329
+ this.blobCache.set(mimeType, blob2);
330
+ return blob2;
331
+ }
332
+ const dataUri = await this.getDataUri(mimeType);
333
+ const blob = dataUriToBlob(dataUri);
334
+ this.blobCache.set(mimeType, blob);
335
+ return blob;
336
+ }
337
+ async toFirstSupported(supports) {
338
+ const canonical = this.canonicalSupport();
339
+ if (canonical && supports.includes(canonical)) {
340
+ return this.currentSourceValue();
341
+ }
342
+ for (const want of supports) {
343
+ switch (want) {
344
+ case "ImageBinary":
345
+ return this.getPixels();
346
+ case "Blob":
347
+ return this.getBlob();
348
+ case "DataUri":
349
+ return this.getDataUri();
350
+ case "RawImage": {
351
+ const p = await this.getPixels();
352
+ return new MediaRawImage(p.data, p.width, p.height, p.channels);
353
+ }
354
+ case "ImageBitmap":
355
+ case "VideoFrame":
356
+ case "OffscreenCanvas": {
357
+ const asBrowser = this;
358
+ if (asBrowser.toFirstSupportedBrowser) {
359
+ const produced = await asBrowser.toFirstSupportedBrowser(want);
360
+ if (produced !== undefined)
361
+ return produced;
362
+ }
363
+ continue;
364
+ }
365
+ case "Sharp":
366
+ continue;
367
+ }
368
+ }
369
+ throw new Error(`Image.toFirstSupported: none of [${supports.join(", ")}] can be produced on this platform`);
370
+ }
371
+ toJSON() {
372
+ if (this.source.kind === "dataUri") {
373
+ return this.source.dataUri;
374
+ }
375
+ const pixels = this.source.kind === "pixels" ? this.source.pixels : this.pixelsCache;
376
+ if (pixels) {
377
+ return {
378
+ data: Array.from(pixels.data),
379
+ width: pixels.width,
380
+ height: pixels.height,
381
+ channels: pixels.channels
382
+ };
383
+ }
384
+ return { unsynced: true, kind: this.source.kind };
385
+ }
386
+ canonicalSupport() {
387
+ switch (this.source.kind) {
388
+ case "dataUri":
389
+ return "DataUri";
390
+ case "pixels":
391
+ return "ImageBinary";
392
+ case "blob":
393
+ return "Blob";
394
+ case "bitmap":
395
+ return "ImageBitmap";
396
+ case "videoFrame":
397
+ return "VideoFrame";
398
+ case "offscreenCanvas":
399
+ return "OffscreenCanvas";
400
+ }
401
+ }
402
+ getSource() {
403
+ return this.source;
404
+ }
405
+ setPixelsCache(pixels) {
406
+ this.pixelsCache = pixels;
407
+ }
408
+ currentSourceValue() {
409
+ switch (this.source.kind) {
410
+ case "dataUri":
411
+ return this.source.dataUri;
412
+ case "pixels":
413
+ return this.source.pixels;
414
+ case "blob":
415
+ return this.source.blob;
416
+ case "bitmap":
417
+ return this.source.bitmap;
418
+ case "videoFrame":
419
+ return this.source.frame;
420
+ case "offscreenCanvas":
421
+ return this.source.canvas;
422
+ }
423
+ }
424
+ }
425
+ async function blobToDataUri(blob) {
426
+ const buffer = await blob.arrayBuffer();
427
+ const bytes = new Uint8Array(buffer);
428
+ let binary = "";
429
+ const CHUNK = 8192;
430
+ for (let i = 0;i < bytes.byteLength; i += CHUNK) {
431
+ binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
432
+ }
433
+ const mime = blob.type || "image/png";
434
+ return `data:${mime};base64,${btoa(binary)}`;
67
435
  }
436
+ // src/media/Image.browser.ts
437
+ Image.fromBitmap = function fromBitmap(bitmap) {
438
+ return Image.from(bitmap);
439
+ };
440
+ Image.fromVideoFrame = function fromVideoFrame(frame) {
441
+ return Image.from(frame);
442
+ };
443
+ Image.fromOffscreenCanvas = function fromOffscreenCanvas(canvas) {
444
+ return Image.from(canvas);
445
+ };
446
+ function rasterToImageData(image) {
447
+ const { width, height, channels, data } = image;
448
+ const id = new ImageData(width, height);
449
+ if (channels === 4) {
450
+ id.data.set(data);
451
+ return id;
452
+ }
453
+ if (channels === 3) {
454
+ for (let i = 0;i < width * height; i++) {
455
+ id.data[i * 4] = data[i * 3];
456
+ id.data[i * 4 + 1] = data[i * 3 + 1];
457
+ id.data[i * 4 + 2] = data[i * 3 + 2];
458
+ id.data[i * 4 + 3] = 255;
459
+ }
460
+ return id;
461
+ }
462
+ if (channels === 1) {
463
+ for (let i = 0;i < width * height; i++) {
464
+ const v = data[i];
465
+ id.data[i * 4] = v;
466
+ id.data[i * 4 + 1] = v;
467
+ id.data[i * 4 + 2] = v;
468
+ id.data[i * 4 + 3] = 255;
469
+ }
470
+ return id;
471
+ }
472
+ throw new Error(`Image.getImageData: unsupported channel count ${channels}`);
473
+ }
474
+ async function blobToOffscreenCanvas(blob) {
475
+ const bitmap = await createImageBitmap(blob);
476
+ try {
477
+ const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
478
+ const ctx = canvas.getContext("2d");
479
+ if (!ctx)
480
+ throw new Error("Image: failed to get 2D context on OffscreenCanvas");
481
+ ctx.drawImage(bitmap, 0, 0);
482
+ return canvas;
483
+ } finally {
484
+ bitmap.close();
485
+ }
486
+ }
487
+ Image.prototype.getImageData = async function getImageData() {
488
+ const pixels = await this.getPixels();
489
+ return rasterToImageData(pixels);
490
+ };
491
+ Image.prototype.getImageBitmap = async function getImageBitmap() {
492
+ const source = this.getSource();
493
+ if (source.kind === "bitmap")
494
+ return source.bitmap;
495
+ if (source.kind === "blob")
496
+ return createImageBitmap(source.blob);
497
+ if (source.kind === "offscreenCanvas") {
498
+ return source.canvas.transferToImageBitmap();
499
+ }
500
+ if (source.kind === "dataUri") {
501
+ return createImageBitmap(dataUriToBlob(source.dataUri));
502
+ }
503
+ const id = await this.getImageData();
504
+ return createImageBitmap(id);
505
+ };
506
+ Image.prototype.getVideoFrame = async function getVideoFrame() {
507
+ const source = this.getSource();
508
+ if (source.kind === "videoFrame")
509
+ return source.frame;
510
+ const bitmap = await this.getImageBitmap();
511
+ return new VideoFrame(bitmap, { timestamp: 0 });
512
+ };
513
+ Image.prototype.getOffscreenCanvas = async function getOffscreenCanvas() {
514
+ const source = this.getSource();
515
+ if (source.kind === "offscreenCanvas")
516
+ return source.canvas;
517
+ if (source.kind === "blob")
518
+ return blobToOffscreenCanvas(source.blob);
519
+ if (source.kind === "dataUri")
520
+ return blobToOffscreenCanvas(dataUriToBlob(source.dataUri));
521
+ const id = await this.getImageData();
522
+ const canvas = new OffscreenCanvas(id.width, id.height);
523
+ const ctx = canvas.getContext("2d");
524
+ if (!ctx)
525
+ throw new Error("Image.getOffscreenCanvas: failed to get 2D context");
526
+ ctx.putImageData(id, 0, 0);
527
+ return canvas;
528
+ };
529
+ Image.prototype.toFirstSupportedBrowser = async function toFirstSupportedBrowser(want) {
530
+ if (want === "ImageBitmap")
531
+ return this.getImageBitmap();
532
+ if (want === "VideoFrame")
533
+ return this.getVideoFrame();
534
+ if (want === "OffscreenCanvas")
535
+ return this.getOffscreenCanvas();
536
+ return;
537
+ };
68
538
  export {
539
+ toHexColor,
540
+ resolveColor,
541
+ registerImageRasterCodec,
542
+ parseHexColor,
69
543
  parseDataUri,
70
- convertImageDataToUseableForm
544
+ isMediaRawImageShape,
545
+ isHexColor,
546
+ isColorObject,
547
+ getImageRasterCodec,
548
+ dataUriToBlob,
549
+ MediaRawImage,
550
+ Image
71
551
  };
72
552
 
73
- //# debugId=7D52B745FDBDACD364756E2164756E21
553
+ //# debugId=9670F06EEC7694A064756E2164756E21