webcodecs-node 0.5.2 → 0.7.0

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 (144) hide show
  1. package/README.md +279 -0
  2. package/dist/backends/types.d.ts +2 -0
  3. package/dist/backends/types.d.ts.map +1 -1
  4. package/dist/backends/types.js.map +1 -1
  5. package/dist/canvas/canvas-utils.d.ts +115 -0
  6. package/dist/canvas/canvas-utils.d.ts.map +1 -0
  7. package/dist/canvas/canvas-utils.js +169 -0
  8. package/dist/canvas/canvas-utils.js.map +1 -0
  9. package/dist/canvas/frame-loop.d.ts +113 -0
  10. package/dist/canvas/frame-loop.d.ts.map +1 -0
  11. package/dist/canvas/frame-loop.js +291 -0
  12. package/dist/canvas/frame-loop.js.map +1 -0
  13. package/dist/canvas/gpu-context.d.ts +61 -0
  14. package/dist/canvas/gpu-context.d.ts.map +1 -0
  15. package/dist/canvas/gpu-context.js +134 -0
  16. package/dist/canvas/gpu-context.js.map +1 -0
  17. package/dist/canvas/index.d.ts +22 -0
  18. package/dist/canvas/index.d.ts.map +1 -0
  19. package/dist/canvas/index.js +25 -0
  20. package/dist/canvas/index.js.map +1 -0
  21. package/dist/canvas/types.d.ts +101 -0
  22. package/dist/canvas/types.d.ts.map +1 -0
  23. package/dist/canvas/types.js +7 -0
  24. package/dist/canvas/types.js.map +1 -0
  25. package/dist/codec-utils/formats.d.ts.map +1 -1
  26. package/dist/codec-utils/formats.js +31 -0
  27. package/dist/codec-utils/formats.js.map +1 -1
  28. package/dist/config/ffmpeg-quality.d.ts +14 -0
  29. package/dist/config/ffmpeg-quality.d.ts.map +1 -0
  30. package/dist/config/ffmpeg-quality.js +41 -0
  31. package/dist/config/ffmpeg-quality.js.map +1 -0
  32. package/dist/containers/Muxer.d.ts.map +1 -1
  33. package/dist/containers/Muxer.js +4 -1
  34. package/dist/containers/Muxer.js.map +1 -1
  35. package/dist/core/AudioData.d.ts +2 -1
  36. package/dist/core/AudioData.d.ts.map +1 -1
  37. package/dist/core/AudioData.js.map +1 -1
  38. package/dist/core/VideoFrame.d.ts +2 -2
  39. package/dist/core/VideoFrame.d.ts.map +1 -1
  40. package/dist/core/VideoFrame.js +49 -47
  41. package/dist/core/VideoFrame.js.map +1 -1
  42. package/dist/decoders/AudioDecoder.d.ts +1 -0
  43. package/dist/decoders/AudioDecoder.d.ts.map +1 -1
  44. package/dist/decoders/AudioDecoder.js +39 -17
  45. package/dist/decoders/AudioDecoder.js.map +1 -1
  46. package/dist/decoders/ImageDecoder.d.ts +1 -0
  47. package/dist/decoders/ImageDecoder.d.ts.map +1 -1
  48. package/dist/decoders/ImageDecoder.js +40 -3
  49. package/dist/decoders/ImageDecoder.js.map +1 -1
  50. package/dist/decoders/VideoDecoder.d.ts +12 -0
  51. package/dist/decoders/VideoDecoder.d.ts.map +1 -1
  52. package/dist/decoders/VideoDecoder.js +50 -8
  53. package/dist/decoders/VideoDecoder.js.map +1 -1
  54. package/dist/demos/demo-1080p-transcode.js +8 -2
  55. package/dist/demos/demo-1080p-transcode.js.map +1 -1
  56. package/dist/demos/demo-audio-visualizer.d.ts +11 -0
  57. package/dist/demos/demo-audio-visualizer.d.ts.map +1 -0
  58. package/dist/demos/demo-audio-visualizer.js +281 -0
  59. package/dist/demos/demo-audio-visualizer.js.map +1 -0
  60. package/dist/demos/demo-dvd-logo.d.ts +8 -0
  61. package/dist/demos/demo-dvd-logo.d.ts.map +1 -0
  62. package/dist/demos/demo-dvd-logo.js +196 -0
  63. package/dist/demos/demo-dvd-logo.js.map +1 -0
  64. package/dist/demos/demo-four-corners.js +9 -0
  65. package/dist/demos/demo-four-corners.js.map +1 -1
  66. package/dist/demos/demo-streaming.js +6 -0
  67. package/dist/demos/demo-streaming.js.map +1 -1
  68. package/dist/demos/demo-webcodecs.js +1 -0
  69. package/dist/demos/demo-webcodecs.js.map +1 -1
  70. package/dist/encoders/AudioEncoder.d.ts +3 -0
  71. package/dist/encoders/AudioEncoder.d.ts.map +1 -1
  72. package/dist/encoders/AudioEncoder.js +70 -28
  73. package/dist/encoders/AudioEncoder.js.map +1 -1
  74. package/dist/encoders/ImageEncoder.d.ts +80 -0
  75. package/dist/encoders/ImageEncoder.d.ts.map +1 -0
  76. package/dist/encoders/ImageEncoder.js +156 -0
  77. package/dist/encoders/ImageEncoder.js.map +1 -0
  78. package/dist/encoders/VideoEncoder.d.ts +11 -0
  79. package/dist/encoders/VideoEncoder.d.ts.map +1 -1
  80. package/dist/encoders/VideoEncoder.js +46 -4
  81. package/dist/encoders/VideoEncoder.js.map +1 -1
  82. package/dist/encoders/index.d.ts +1 -0
  83. package/dist/encoders/index.d.ts.map +1 -1
  84. package/dist/encoders/index.js +1 -0
  85. package/dist/encoders/index.js.map +1 -1
  86. package/dist/formats/color-space.d.ts +88 -0
  87. package/dist/formats/color-space.d.ts.map +1 -1
  88. package/dist/formats/color-space.js +55 -1
  89. package/dist/formats/color-space.js.map +1 -1
  90. package/dist/formats/pixel-formats.d.ts +17 -1
  91. package/dist/formats/pixel-formats.d.ts.map +1 -1
  92. package/dist/formats/pixel-formats.js +74 -4
  93. package/dist/formats/pixel-formats.js.map +1 -1
  94. package/dist/hardware/detection.d.ts.map +1 -1
  95. package/dist/hardware/detection.js +5 -2
  96. package/dist/hardware/detection.js.map +1 -1
  97. package/dist/hardware/encoder-args.d.ts.map +1 -1
  98. package/dist/hardware/encoder-args.js +6 -6
  99. package/dist/hardware/encoder-args.js.map +1 -1
  100. package/dist/index.d.ts +11 -3
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +8 -2
  103. package/dist/index.js.map +1 -1
  104. package/dist/node-av/NodeAvAudioDecoder.d.ts.map +1 -1
  105. package/dist/node-av/NodeAvAudioDecoder.js +3 -0
  106. package/dist/node-av/NodeAvAudioDecoder.js.map +1 -1
  107. package/dist/node-av/NodeAvAudioEncoder.d.ts +5 -0
  108. package/dist/node-av/NodeAvAudioEncoder.d.ts.map +1 -1
  109. package/dist/node-av/NodeAvAudioEncoder.js +102 -9
  110. package/dist/node-av/NodeAvAudioEncoder.js.map +1 -1
  111. package/dist/node-av/NodeAvVideoEncoder.d.ts +2 -0
  112. package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -1
  113. package/dist/node-av/NodeAvVideoEncoder.js +44 -6
  114. package/dist/node-av/NodeAvVideoEncoder.js.map +1 -1
  115. package/dist/node-av/WebPImageDecoder.d.ts +54 -0
  116. package/dist/node-av/WebPImageDecoder.d.ts.map +1 -0
  117. package/dist/node-av/WebPImageDecoder.js +176 -0
  118. package/dist/node-av/WebPImageDecoder.js.map +1 -0
  119. package/dist/polyfills/OffscreenCanvas.d.ts +141 -7
  120. package/dist/polyfills/OffscreenCanvas.d.ts.map +1 -1
  121. package/dist/polyfills/OffscreenCanvas.js +217 -17
  122. package/dist/polyfills/OffscreenCanvas.js.map +1 -1
  123. package/dist/types/index.d.ts +1 -0
  124. package/dist/types/index.d.ts.map +1 -1
  125. package/dist/types/index.js +2 -0
  126. package/dist/types/index.js.map +1 -1
  127. package/dist/types/native-frame.d.ts +74 -0
  128. package/dist/types/native-frame.d.ts.map +1 -0
  129. package/dist/types/native-frame.js +32 -0
  130. package/dist/types/native-frame.js.map +1 -0
  131. package/dist/utils/index.d.ts +1 -1
  132. package/dist/utils/index.d.ts.map +1 -1
  133. package/dist/utils/index.js +1 -1
  134. package/dist/utils/index.js.map +1 -1
  135. package/dist/utils/type-guards.d.ts +29 -1
  136. package/dist/utils/type-guards.d.ts.map +1 -1
  137. package/dist/utils/type-guards.js +47 -2
  138. package/dist/utils/type-guards.js.map +1 -1
  139. package/docs/api.md +155 -0
  140. package/docs/configuration.md +27 -0
  141. package/examples/README.md +28 -1
  142. package/examples/canvas-encoding.ts +222 -0
  143. package/examples/offscreen-canvas.ts +230 -0
  144. package/package.json +9 -3
package/README.md CHANGED
@@ -9,6 +9,7 @@ This package provides a Node.js-compatible implementation of the [WebCodecs API]
9
9
  - **VideoEncoder / VideoDecoder** - H.264, HEVC, VP8, VP9, AV1
10
10
  - **AudioEncoder / AudioDecoder** - AAC, Opus, MP3, FLAC, Vorbis
11
11
  - **ImageDecoder** - PNG, JPEG, WebP, GIF, AVIF, BMP, TIFF (including animated with frame timing)
12
+ - **ImageEncoder** - Encode VideoFrames to PNG, JPEG, WebP
12
13
  - **VideoFrame / AudioData** - Frame-level data manipulation
13
14
  - **MediaCapabilities** - Query codec support, smooth playback, and power efficiency
14
15
  - **Hardware Acceleration** - VAAPI, NVENC, QSV support
@@ -16,6 +17,7 @@ This package provides a Node.js-compatible implementation of the [WebCodecs API]
16
17
  - **Latency Modes** - Configure for real-time streaming vs maximum compression
17
18
  - **Bitrate Modes** - Constant, variable, and quantizer (CRF) encoding modes
18
19
  - **Alpha Channel** - Preserve transparency with VP9 and AV1 codecs
20
+ - **10-bit & HDR** - I420P10, P010 formats with HDR10 metadata support
19
21
  - **Container Support** - MP4, WebM demuxing/muxing utilities
20
22
 
21
23
  ## Documentation
@@ -246,6 +248,36 @@ decoder.close();
246
248
  - `image/bmp`
247
249
  - `image/tiff`
248
250
 
251
+ ### ImageEncoder
252
+
253
+ Encodes VideoFrames to image formats (PNG, JPEG, WebP). This is a utility class that mirrors ImageDecoder.
254
+
255
+ ```typescript
256
+ import { ImageEncoder, VideoFrame } from 'webcodecs-node';
257
+
258
+ // Check format support
259
+ ImageEncoder.isTypeSupported('image/webp'); // true
260
+
261
+ // Encode a frame to JPEG
262
+ const result = await ImageEncoder.encode(frame, {
263
+ type: 'image/jpeg',
264
+ quality: 0.85,
265
+ });
266
+
267
+ fs.writeFileSync('output.jpg', Buffer.from(result.data));
268
+
269
+ // Synchronous encoding
270
+ const pngResult = ImageEncoder.encodeSync(frame, { type: 'image/png' });
271
+
272
+ // Batch encode multiple frames
273
+ const results = await ImageEncoder.encodeBatch(frames, { type: 'image/webp' });
274
+ ```
275
+
276
+ **Supported output formats:**
277
+ - `image/png` - Lossless, supports transparency
278
+ - `image/jpeg` - Lossy, quality 0-1 (default: 0.92)
279
+ - `image/webp` - Lossy/lossless, quality 0-1 (default: 0.8)
280
+
249
281
  ### MediaCapabilities API
250
282
 
251
283
  Query codec capabilities before encoding/decoding. Implements the standard [MediaCapabilities API](https://developer.mozilla.org/en-US/docs/Web/API/MediaCapabilities).
@@ -419,6 +451,207 @@ const frame = new VideoFrame(rgbaWithAlpha, {
419
451
  encoder.encode(frame);
420
452
  ```
421
453
 
454
+ ### 10-bit Pixel Formats & HDR
455
+
456
+ Support for high bit-depth content and HDR metadata:
457
+
458
+ ```typescript
459
+ import {
460
+ VideoFrame,
461
+ VideoColorSpace,
462
+ createHdr10MasteringMetadata,
463
+ createContentLightLevel,
464
+ is10BitFormat,
465
+ getBitDepth,
466
+ } from 'webcodecs-node';
467
+
468
+ // Create a 10-bit frame
469
+ const frame = new VideoFrame(yuv10bitData, {
470
+ format: 'I420P10', // 10-bit YUV 4:2:0
471
+ codedWidth: 3840,
472
+ codedHeight: 2160,
473
+ timestamp: 0,
474
+ colorSpace: new VideoColorSpace({
475
+ primaries: 'bt2020',
476
+ transfer: 'pq', // HDR10 PQ transfer
477
+ matrix: 'bt2020-ncl',
478
+ }),
479
+ });
480
+
481
+ // Check format properties
482
+ console.log(is10BitFormat('I420P10')); // true
483
+ console.log(getBitDepth('I420P10')); // 10
484
+
485
+ // HDR metadata for mastering display
486
+ const hdrMetadata = {
487
+ smpteSt2086: createHdr10MasteringMetadata(1000, 0.0001), // max/min luminance
488
+ contentLightLevel: createContentLightLevel(800, 400), // MaxCLL, MaxFALL
489
+ };
490
+
491
+ const colorSpace = new VideoColorSpace({
492
+ primaries: 'bt2020',
493
+ transfer: 'pq',
494
+ hdrMetadata,
495
+ });
496
+
497
+ console.log(colorSpace.isHdr); // true
498
+ console.log(colorSpace.hasHdrMetadata); // true
499
+ ```
500
+
501
+ **10-bit pixel formats:**
502
+ - `I420P10` - YUV 4:2:0 planar, 10-bit
503
+ - `I422P10` - YUV 4:2:2 planar, 10-bit
504
+ - `I444P10` - YUV 4:4:4 planar, 10-bit
505
+ - `P010` - YUV 4:2:0 semi-planar, 10-bit
506
+
507
+ **Pixel format utilities:**
508
+ - `is10BitFormat(format)` - Check if format is 10-bit
509
+ - `getBitDepth(format)` - Get bit depth (8 or 10)
510
+ - `get8BitEquivalent(format)` - Get 8-bit version of a 10-bit format
511
+ - `get10BitEquivalent(format)` - Get 10-bit version of an 8-bit format
512
+
513
+ ### Canvas Rendering (skia-canvas)
514
+
515
+ GPU-accelerated 2D canvas rendering with automatic hardware detection:
516
+
517
+ ```typescript
518
+ import {
519
+ createCanvas,
520
+ createFrameLoop,
521
+ detectGpuAcceleration,
522
+ isGpuAvailable,
523
+ getGpuApi,
524
+ ensureEvenDimensions,
525
+ VideoEncoder,
526
+ } from 'webcodecs-node';
527
+
528
+ // Check GPU availability
529
+ const gpuInfo = detectGpuAcceleration();
530
+ console.log(`Renderer: ${gpuInfo.renderer}`); // 'GPU' or 'CPU'
531
+ console.log(`API: ${getGpuApi()}`); // 'Metal', 'Vulkan', 'D3D', or null
532
+
533
+ // Create GPU-accelerated canvas
534
+ const canvas = createCanvas({
535
+ width: 1920,
536
+ height: 1080,
537
+ gpu: true, // or omit for auto-detection
538
+ });
539
+
540
+ const ctx = canvas.getContext('2d');
541
+ ctx.fillStyle = 'red';
542
+ ctx.fillRect(0, 0, 1920, 1080);
543
+
544
+ // Create VideoFrame directly from canvas
545
+ const frame = new VideoFrame(canvas, { timestamp: 0 });
546
+ ```
547
+
548
+ **FrameLoop helper** for animation with backpressure:
549
+
550
+ ```typescript
551
+ const loop = createFrameLoop({
552
+ width: 1920,
553
+ height: 1080,
554
+ frameRate: 30,
555
+ maxQueueSize: 8, // Backpressure limit
556
+ onFrame: (ctx, timing) => {
557
+ // Draw each frame
558
+ ctx.fillStyle = `hsl(${timing.frameIndex % 360}, 100%, 50%)`;
559
+ ctx.fillRect(0, 0, 1920, 1080);
560
+ },
561
+ });
562
+
563
+ loop.start(300); // Generate 300 frames
564
+
565
+ while (loop.getState() !== 'stopped' || loop.getQueueSize() > 0) {
566
+ const frame = loop.takeFrame();
567
+ if (frame) {
568
+ encoder.encode(frame);
569
+ frame.close(); // Always close frames!
570
+ }
571
+ }
572
+ ```
573
+
574
+ **OffscreenCanvas polyfill** for browser-compatible code:
575
+
576
+ ```typescript
577
+ import { installOffscreenCanvasPolyfill } from 'webcodecs-node';
578
+
579
+ installOffscreenCanvasPolyfill();
580
+
581
+ // Now use standard OffscreenCanvas API
582
+ const canvas = new OffscreenCanvas(1920, 1080);
583
+ const ctx = canvas.getContext('2d');
584
+ const blob = await canvas.convertToBlob({ type: 'image/png' });
585
+ ```
586
+
587
+ ## Performance Tuning
588
+
589
+ ### Memory Management
590
+
591
+ Always close VideoFrames and AudioData when done:
592
+
593
+ ```typescript
594
+ const frame = new VideoFrame(buffer, { ... });
595
+ try {
596
+ encoder.encode(frame);
597
+ } finally {
598
+ frame.close(); // Prevent memory leaks
599
+ }
600
+ ```
601
+
602
+ ### Even Dimensions
603
+
604
+ Video codecs require even dimensions for YUV420 chroma subsampling:
605
+
606
+ ```typescript
607
+ import { ensureEvenDimensions, validateEvenDimensions } from 'webcodecs-node';
608
+
609
+ // Auto-fix odd dimensions (rounds up)
610
+ const { width, height } = ensureEvenDimensions(1279, 719);
611
+ // Returns { width: 1280, height: 720 }
612
+
613
+ // Strict validation (throws if odd)
614
+ validateEvenDimensions(1280, 720); // OK
615
+ validateEvenDimensions(1279, 720); // Throws TypeError
616
+ ```
617
+
618
+ ### Backpressure Handling
619
+
620
+ Monitor encoder queue to prevent memory exhaustion:
621
+
622
+ ```typescript
623
+ encoder.addEventListener('dequeue', () => {
624
+ // Queue size decreased, safe to encode more
625
+ if (encoder.encodeQueueSize < 10) {
626
+ encodeNextFrame();
627
+ }
628
+ });
629
+ ```
630
+
631
+ ### Raw Buffer Export
632
+
633
+ For maximum performance, use raw RGBA buffers instead of PNG/JPEG:
634
+
635
+ ```typescript
636
+ import { getRawPixels } from 'webcodecs-node';
637
+
638
+ // Fast: raw RGBA buffer (no compression)
639
+ const pixels = getRawPixels(canvas); // Returns Buffer
640
+
641
+ // Slow: PNG encoding (avoid in hot paths)
642
+ const png = await canvas.toBuffer('png');
643
+ ```
644
+
645
+ ### GPU vs CPU Tradeoffs
646
+
647
+ | Scenario | Recommendation |
648
+ |----------|----------------|
649
+ | HD/4K encoding | `hardwareAcceleration: 'prefer-hardware'` |
650
+ | Real-time streaming | Hardware + `latencyMode: 'realtime'` |
651
+ | Maximum quality | Software + `bitrateMode: 'quantizer'` |
652
+ | Batch processing | Hardware for throughput |
653
+ | Low-end systems | Software (more compatible) |
654
+
422
655
  ## Demos
423
656
 
424
657
  Run the included demos to test functionality:
@@ -452,6 +685,52 @@ npm run demo:fourcorners
452
685
 
453
686
  # 1080p transcoding demo
454
687
  npm run demo:1080p
688
+
689
+ # DVD bouncing logo animation
690
+ npm run demo:dvd
691
+
692
+ # Audio visualizer with waveform and spectrum
693
+ npm run demo:visualizer
694
+ ```
695
+
696
+ ## Benchmarking
697
+
698
+ Compare software vs hardware encoding performance:
699
+
700
+ ```bash
701
+ # Quick benchmark (30 frames, 360p)
702
+ npm run bench:quick
703
+
704
+ # Default benchmark (120 frames, 720p)
705
+ npm run bench
706
+
707
+ # Full benchmark (300 frames, 1080p)
708
+ npm run bench:full
709
+
710
+ # Custom options
711
+ node scripts/encoding-benchmark.mjs --frames 100 --resolution 1080p --codecs h264,hevc
712
+ ```
713
+
714
+ **Options:**
715
+ - `--frames <n>` - Number of frames to encode (default: 120)
716
+ - `--resolution <res>` - 360p, 480p, 720p, 1080p, 4k (default: 720p)
717
+ - `--bitrate <bps>` - Target bitrate in bps
718
+ - `--framerate <fps>` - Target framerate (default: 30)
719
+ - `--codecs <list>` - Comma-separated: h264,hevc,vp9,av1
720
+ - `--skip-software` - Only test hardware encoding
721
+ - `--verbose` - Show detailed output
722
+
723
+ **Example output:**
724
+ ```
725
+ ════════════════════════════════════════════════════════════════════════════════
726
+ ENCODING BENCHMARK RESULTS (720p)
727
+ ════════════════════════════════════════════════════════════════════════════════
728
+ Codec Mode FPS Time Latency Size Bitrate
729
+ ────────────────────────────────────────────────────────────────────────────────
730
+ H.264/AVC SW 213.6 562ms 391ms 2.00 MB 4.20 Mbps
731
+ H.264/AVC HW 370.4 324ms 187ms 2.11 MB 4.43 Mbps
732
+ H.265/HEVC SW 141.4 848ms 106ms 1.94 MB 4.06 Mbps
733
+ H.265/HEVC HW 589.0 204ms 61ms 2.16 MB 4.54 Mbps
455
734
  ```
456
735
 
457
736
  ## API Compatibility
@@ -40,6 +40,8 @@ export interface VideoEncoderBackendConfig {
40
40
  latencyMode?: 'quality' | 'realtime';
41
41
  alpha?: 'discard' | 'keep';
42
42
  hardwareAcceleration?: 'no-preference' | 'prefer-hardware' | 'prefer-software';
43
+ /** Output format: 'annexb' for raw Annex B, 'mp4' for length-prefixed (AVCC/HVCC) */
44
+ format?: 'annexb' | 'mp4';
43
45
  }
44
46
  /**
45
47
  * Video decoder configuration
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgLH,iDAAiD;AACjD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE3C,wDAAwD;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,2CAA2C;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C,4CAA4C;AAC5C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,EAAE;IACP,GAAG,EAAE,EAAE;IACP,GAAG,EAAE,EAAE;CACC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkLH,iDAAiD;AACjD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE3C,wDAAwD;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,2CAA2C;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C,4CAA4C;AAC5C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,EAAE;IACP,GAAG,EAAE,EAAE;IACP,GAAG,EAAE,EAAE;CACC,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Canvas Utilities for skia-canvas
3
+ *
4
+ * Raw buffer utilities for efficient pixel data handling.
5
+ * Always uses toBuffer('raw') - never PNG or other encoded formats.
6
+ */
7
+ import { Canvas } from 'skia-canvas';
8
+ import type { RawBufferOptions } from './types.js';
9
+ /**
10
+ * Create a pixel buffer for image manipulation
11
+ *
12
+ * Uses Uint8ClampedArray which automatically clamps values to 0-255,
13
+ * preventing overflow bugs in filters and pixel manipulation code.
14
+ *
15
+ * @param width - Image width in pixels
16
+ * @param height - Image height in pixels
17
+ * @returns Uint8ClampedArray of size width * height * 4 (RGBA)
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const pixels = createPixelBuffer(1920, 1080);
22
+ * // Safe manipulation - values auto-clamped to 0-255
23
+ * pixels[0] = 300; // Becomes 255
24
+ * pixels[1] = -50; // Becomes 0
25
+ * ```
26
+ */
27
+ export declare function createPixelBuffer(width: number, height: number): Uint8ClampedArray;
28
+ /**
29
+ * Create a pixel buffer initialized with a solid color
30
+ *
31
+ * @param width - Image width in pixels
32
+ * @param height - Image height in pixels
33
+ * @param r - Red component (0-255)
34
+ * @param g - Green component (0-255)
35
+ * @param b - Blue component (0-255)
36
+ * @param a - Alpha component (0-255, default 255)
37
+ * @returns Uint8ClampedArray filled with the specified color
38
+ */
39
+ export declare function createPixelBufferWithColor(width: number, height: number, r: number, g: number, b: number, a?: number): Uint8ClampedArray;
40
+ /**
41
+ * Get raw RGBA pixel data from canvas (synchronous)
42
+ * ALWAYS uses toBufferSync('raw') - never PNG or other encoded formats.
43
+ *
44
+ * @param canvas - The skia-canvas Canvas instance
45
+ * @param options - Optional buffer format options
46
+ * @returns Buffer containing raw RGBA pixel data
47
+ */
48
+ export declare function getRawPixels(canvas: Canvas, options?: RawBufferOptions): Buffer;
49
+ /**
50
+ * Get raw RGBA pixel data from canvas (asynchronous)
51
+ * ALWAYS uses toBuffer('raw') - never PNG or other encoded formats.
52
+ *
53
+ * @param canvas - The skia-canvas Canvas instance
54
+ * @param options - Optional buffer format options
55
+ * @returns Promise resolving to Buffer containing raw RGBA pixel data
56
+ */
57
+ export declare function getRawPixelsAsync(canvas: Canvas, options?: RawBufferOptions): Promise<Buffer>;
58
+ /**
59
+ * Reset canvas state for new frame
60
+ *
61
+ * Prevents Skia command history buildup which can cause memory
62
+ * growth and performance degradation over time.
63
+ *
64
+ * @param ctx - The 2D rendering context
65
+ */
66
+ export declare function resetCanvas(ctx: CanvasRenderingContext2D): void;
67
+ /**
68
+ * Simple ImageData-like object for internal use
69
+ */
70
+ export interface SimpleImageData {
71
+ data: Uint8ClampedArray;
72
+ width: number;
73
+ height: number;
74
+ colorSpace?: string;
75
+ colorType?: string;
76
+ }
77
+ /**
78
+ * Convert Uint8Array/Buffer to ImageData-like object
79
+ * Compatible with skia-canvas putImageData
80
+ *
81
+ * @param data - Raw pixel data (RGBA format)
82
+ * @param width - Image width in pixels
83
+ * @param height - Image height in pixels
84
+ * @returns ImageData-like object
85
+ */
86
+ export declare function pixelsToImageData(data: Uint8Array | Buffer, width: number, height: number): SimpleImageData;
87
+ /**
88
+ * Draw raw RGBA pixels to canvas
89
+ *
90
+ * @param canvas - The skia-canvas Canvas instance
91
+ * @param data - Raw pixel data (RGBA format)
92
+ * @param width - Image width in pixels
93
+ * @param height - Image height in pixels
94
+ */
95
+ export declare function drawPixelsToCanvas(canvas: Canvas, data: Uint8Array | Buffer, width: number, height: number): void;
96
+ /**
97
+ * Create a Uint8Array view of a Buffer without copying
98
+ *
99
+ * @param buffer - Node.js Buffer
100
+ * @returns Uint8Array view of the same memory
101
+ */
102
+ export declare function bufferToUint8Array(buffer: Buffer): Uint8Array;
103
+ /**
104
+ * Resize raw pixel data using canvas
105
+ *
106
+ * @param data - Source pixel data (RGBA format)
107
+ * @param srcWidth - Source width
108
+ * @param srcHeight - Source height
109
+ * @param dstWidth - Destination width
110
+ * @param dstHeight - Destination height
111
+ * @param canvas - Optional canvas to reuse (for performance)
112
+ * @returns Resized pixel data as Buffer
113
+ */
114
+ export declare function resizePixels(data: Uint8Array | Buffer, srcWidth: number, srcHeight: number, dstWidth: number, dstHeight: number, canvas?: Canvas): Buffer;
115
+ //# sourceMappingURL=canvas-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-utils.d.ts","sourceRoot":"","sources":["../../src/canvas/canvas-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAElF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,GAAE,MAAY,GACd,iBAAiB,CASnB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAI/E;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,wBAAwB,GAAG,IAAI,CAW/D;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,GAAG,MAAM,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,eAAe,CAajB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,GAAG,MAAM,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,IAAI,CAIN;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAE7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,GAAG,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAqBR"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Canvas Utilities for skia-canvas
3
+ *
4
+ * Raw buffer utilities for efficient pixel data handling.
5
+ * Always uses toBuffer('raw') - never PNG or other encoded formats.
6
+ */
7
+ import { Canvas } from 'skia-canvas';
8
+ /**
9
+ * Create a pixel buffer for image manipulation
10
+ *
11
+ * Uses Uint8ClampedArray which automatically clamps values to 0-255,
12
+ * preventing overflow bugs in filters and pixel manipulation code.
13
+ *
14
+ * @param width - Image width in pixels
15
+ * @param height - Image height in pixels
16
+ * @returns Uint8ClampedArray of size width * height * 4 (RGBA)
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const pixels = createPixelBuffer(1920, 1080);
21
+ * // Safe manipulation - values auto-clamped to 0-255
22
+ * pixels[0] = 300; // Becomes 255
23
+ * pixels[1] = -50; // Becomes 0
24
+ * ```
25
+ */
26
+ export function createPixelBuffer(width, height) {
27
+ return new Uint8ClampedArray(width * height * 4);
28
+ }
29
+ /**
30
+ * Create a pixel buffer initialized with a solid color
31
+ *
32
+ * @param width - Image width in pixels
33
+ * @param height - Image height in pixels
34
+ * @param r - Red component (0-255)
35
+ * @param g - Green component (0-255)
36
+ * @param b - Blue component (0-255)
37
+ * @param a - Alpha component (0-255, default 255)
38
+ * @returns Uint8ClampedArray filled with the specified color
39
+ */
40
+ export function createPixelBufferWithColor(width, height, r, g, b, a = 255) {
41
+ const pixels = new Uint8ClampedArray(width * height * 4);
42
+ for (let i = 0; i < pixels.length; i += 4) {
43
+ pixels[i] = r;
44
+ pixels[i + 1] = g;
45
+ pixels[i + 2] = b;
46
+ pixels[i + 3] = a;
47
+ }
48
+ return pixels;
49
+ }
50
+ /**
51
+ * Get raw RGBA pixel data from canvas (synchronous)
52
+ * ALWAYS uses toBufferSync('raw') - never PNG or other encoded formats.
53
+ *
54
+ * @param canvas - The skia-canvas Canvas instance
55
+ * @param options - Optional buffer format options
56
+ * @returns Buffer containing raw RGBA pixel data
57
+ */
58
+ export function getRawPixels(canvas, options) {
59
+ return canvas.toBufferSync('raw', {
60
+ colorType: options?.colorType ?? 'rgba',
61
+ });
62
+ }
63
+ /**
64
+ * Get raw RGBA pixel data from canvas (asynchronous)
65
+ * ALWAYS uses toBuffer('raw') - never PNG or other encoded formats.
66
+ *
67
+ * @param canvas - The skia-canvas Canvas instance
68
+ * @param options - Optional buffer format options
69
+ * @returns Promise resolving to Buffer containing raw RGBA pixel data
70
+ */
71
+ export async function getRawPixelsAsync(canvas, options) {
72
+ return canvas.toBuffer('raw', {
73
+ colorType: options?.colorType ?? 'rgba',
74
+ });
75
+ }
76
+ /**
77
+ * Reset canvas state for new frame
78
+ *
79
+ * Prevents Skia command history buildup which can cause memory
80
+ * growth and performance degradation over time.
81
+ *
82
+ * @param ctx - The 2D rendering context
83
+ */
84
+ export function resetCanvas(ctx) {
85
+ // Use reset() if available (Canvas API), otherwise clearRect
86
+ if (typeof ctx.reset === 'function') {
87
+ ctx.reset();
88
+ }
89
+ else {
90
+ const canvas = ctx.canvas;
91
+ ctx.save();
92
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
93
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
94
+ ctx.restore();
95
+ }
96
+ }
97
+ /**
98
+ * Convert Uint8Array/Buffer to ImageData-like object
99
+ * Compatible with skia-canvas putImageData
100
+ *
101
+ * @param data - Raw pixel data (RGBA format)
102
+ * @param width - Image width in pixels
103
+ * @param height - Image height in pixels
104
+ * @returns ImageData-like object
105
+ */
106
+ export function pixelsToImageData(data, width, height) {
107
+ const clampedArray = new Uint8ClampedArray(data.buffer, data.byteOffset, data.byteLength);
108
+ return {
109
+ data: clampedArray,
110
+ width,
111
+ height,
112
+ colorSpace: 'srgb',
113
+ colorType: 'rgba', // Required by skia-canvas
114
+ };
115
+ }
116
+ /**
117
+ * Draw raw RGBA pixels to canvas
118
+ *
119
+ * @param canvas - The skia-canvas Canvas instance
120
+ * @param data - Raw pixel data (RGBA format)
121
+ * @param width - Image width in pixels
122
+ * @param height - Image height in pixels
123
+ */
124
+ export function drawPixelsToCanvas(canvas, data, width, height) {
125
+ const ctx = canvas.getContext('2d');
126
+ const imageData = pixelsToImageData(data, width, height);
127
+ ctx.putImageData(imageData, 0, 0);
128
+ }
129
+ /**
130
+ * Create a Uint8Array view of a Buffer without copying
131
+ *
132
+ * @param buffer - Node.js Buffer
133
+ * @returns Uint8Array view of the same memory
134
+ */
135
+ export function bufferToUint8Array(buffer) {
136
+ return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
137
+ }
138
+ /**
139
+ * Resize raw pixel data using canvas
140
+ *
141
+ * @param data - Source pixel data (RGBA format)
142
+ * @param srcWidth - Source width
143
+ * @param srcHeight - Source height
144
+ * @param dstWidth - Destination width
145
+ * @param dstHeight - Destination height
146
+ * @param canvas - Optional canvas to reuse (for performance)
147
+ * @returns Resized pixel data as Buffer
148
+ */
149
+ export function resizePixels(data, srcWidth, srcHeight, dstWidth, dstHeight, canvas) {
150
+ // Create source canvas
151
+ const srcCanvas = new Canvas(srcWidth, srcHeight);
152
+ const srcCtx = srcCanvas.getContext('2d');
153
+ const srcImageData = pixelsToImageData(data, srcWidth, srcHeight);
154
+ srcCtx.putImageData(srcImageData, 0, 0);
155
+ // Create or reuse destination canvas
156
+ const dstCanvas = canvas ?? new Canvas(dstWidth, dstHeight);
157
+ if (dstCanvas.width !== dstWidth || dstCanvas.height !== dstHeight) {
158
+ // Canvas dimensions don't match, need to create new one
159
+ const newDst = new Canvas(dstWidth, dstHeight);
160
+ const dstCtx = newDst.getContext('2d');
161
+ dstCtx.drawImage(srcCanvas, 0, 0, dstWidth, dstHeight);
162
+ return getRawPixels(newDst);
163
+ }
164
+ const dstCtx = dstCanvas.getContext('2d');
165
+ resetCanvas(dstCtx);
166
+ dstCtx.drawImage(srcCanvas, 0, 0, dstWidth, dstHeight);
167
+ return getRawPixels(dstCanvas);
168
+ }
169
+ //# sourceMappingURL=canvas-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-utils.js","sourceRoot":"","sources":["../../src/canvas/canvas-utils.ts"],"names":[],"mappings":"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"}