libbitsub 1.1.0 → 1.2.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.
@@ -0,0 +1,391 @@
1
+ /// <reference types="@webgpu/types" />
2
+ // WGSL Vertex Shader
3
+ const VERTEX_SHADER = /* wgsl */ `
4
+ struct VertexOutput {
5
+ @builtin(position) position: vec4f,
6
+ @location(0) texCoord: vec2f,
7
+ }
8
+
9
+ struct Uniforms {
10
+ resolution: vec2f,
11
+ }
12
+
13
+ struct QuadData {
14
+ destRect: vec4f, // x, y, w, h in pixels
15
+ texSize: vec4f, // texW, texH, 0, 0
16
+ }
17
+
18
+ @group(0) @binding(0) var<uniform> uniforms: Uniforms;
19
+ @group(0) @binding(1) var<storage, read> quadData: QuadData;
20
+
21
+ // Quad vertices (two triangles)
22
+ const QUAD_POSITIONS = array<vec2f, 6>(
23
+ vec2f(0.0, 0.0),
24
+ vec2f(1.0, 0.0),
25
+ vec2f(0.0, 1.0),
26
+ vec2f(1.0, 0.0),
27
+ vec2f(1.0, 1.0),
28
+ vec2f(0.0, 1.0)
29
+ );
30
+
31
+ @vertex
32
+ fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
33
+ var output: VertexOutput;
34
+
35
+ let quadPos = QUAD_POSITIONS[vertexIndex];
36
+ let wh = quadData.destRect.zw;
37
+
38
+ // Calculate pixel position
39
+ let pixelPos = quadData.destRect.xy + quadPos * wh;
40
+
41
+ // Convert to clip space (-1 to 1)
42
+ var clipPos = (pixelPos / uniforms.resolution) * 2.0 - 1.0;
43
+ clipPos.y = -clipPos.y; // Flip Y for canvas coordinates
44
+
45
+ output.position = vec4f(clipPos, 0.0, 1.0);
46
+ output.texCoord = quadPos;
47
+
48
+ return output;
49
+ }
50
+ `;
51
+ // WGSL Fragment Shader - sample RGBA texture directly
52
+ const FRAGMENT_SHADER = /* wgsl */ `
53
+ @group(0) @binding(2) var texSampler: sampler;
54
+ @group(0) @binding(3) var tex: texture_2d<f32>;
55
+
56
+ struct FragmentInput {
57
+ @location(0) texCoord: vec2f,
58
+ }
59
+
60
+ @fragment
61
+ fn fragmentMain(input: FragmentInput) -> @location(0) vec4f {
62
+ // Sample RGBA texture
63
+ let color = textureSample(tex, texSampler, input.texCoord);
64
+
65
+ // Output with premultiplied alpha
66
+ return vec4f(color.rgb * color.a, color.a);
67
+ }
68
+ `;
69
+ /**
70
+ * Check if WebGPU is supported in the current browser.
71
+ */
72
+ export function isWebGPUSupported() {
73
+ return typeof navigator !== 'undefined' && 'gpu' in navigator;
74
+ }
75
+ /**
76
+ * WebGPU-based subtitle renderer.
77
+ * Uploads RGBA bitmap data to GPU textures and renders textured quads.
78
+ */
79
+ export class WebGPURenderer {
80
+ device = null;
81
+ context = null;
82
+ pipeline = null;
83
+ sampler = null;
84
+ bindGroupLayout = null;
85
+ // Uniform buffer for resolution
86
+ uniformBuffer = null;
87
+ // Quad data buffers (one per composition)
88
+ quadDataBuffers = [];
89
+ // Textures for compositions
90
+ textures = [];
91
+ pendingDestroyTextures = [];
92
+ format = 'bgra8unorm';
93
+ _canvas = null;
94
+ _initPromise = null;
95
+ _initialized = false;
96
+ /**
97
+ * Initialize the WebGPU renderer.
98
+ * Returns a promise that resolves when initialization is complete.
99
+ */
100
+ async init() {
101
+ if (this._initPromise)
102
+ return this._initPromise;
103
+ this._initPromise = this._initDevice();
104
+ return this._initPromise;
105
+ }
106
+ async _initDevice() {
107
+ if (!navigator.gpu) {
108
+ throw new Error('WebGPU not supported');
109
+ }
110
+ const adapter = await navigator.gpu.requestAdapter({
111
+ powerPreference: 'high-performance'
112
+ });
113
+ if (!adapter) {
114
+ throw new Error('No WebGPU adapter found');
115
+ }
116
+ this.device = await adapter.requestDevice();
117
+ this.format = navigator.gpu.getPreferredCanvasFormat();
118
+ // Create shader modules
119
+ const vertexModule = this.device.createShaderModule({
120
+ code: VERTEX_SHADER
121
+ });
122
+ const fragmentModule = this.device.createShaderModule({
123
+ code: FRAGMENT_SHADER
124
+ });
125
+ // Create sampler - use linear filtering for smooth scaling
126
+ this.sampler = this.device.createSampler({
127
+ magFilter: 'linear',
128
+ minFilter: 'linear',
129
+ addressModeU: 'clamp-to-edge',
130
+ addressModeV: 'clamp-to-edge'
131
+ });
132
+ // Create uniform buffer
133
+ this.uniformBuffer = this.device.createBuffer({
134
+ size: 16, // vec2f resolution + padding
135
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
136
+ });
137
+ // Create bind group layout
138
+ this.bindGroupLayout = this.device.createBindGroupLayout({
139
+ entries: [
140
+ {
141
+ binding: 0,
142
+ visibility: GPUShaderStage.VERTEX,
143
+ buffer: { type: 'uniform' }
144
+ },
145
+ {
146
+ binding: 1,
147
+ visibility: GPUShaderStage.VERTEX,
148
+ buffer: { type: 'read-only-storage' }
149
+ },
150
+ {
151
+ binding: 2,
152
+ visibility: GPUShaderStage.FRAGMENT,
153
+ sampler: { type: 'filtering' }
154
+ },
155
+ {
156
+ binding: 3,
157
+ visibility: GPUShaderStage.FRAGMENT,
158
+ texture: { sampleType: 'float' }
159
+ }
160
+ ]
161
+ });
162
+ // Create pipeline layout
163
+ const pipelineLayout = this.device.createPipelineLayout({
164
+ bindGroupLayouts: [this.bindGroupLayout]
165
+ });
166
+ // Create render pipeline with alpha blending
167
+ this.pipeline = this.device.createRenderPipeline({
168
+ layout: pipelineLayout,
169
+ vertex: {
170
+ module: vertexModule,
171
+ entryPoint: 'vertexMain'
172
+ },
173
+ fragment: {
174
+ module: fragmentModule,
175
+ entryPoint: 'fragmentMain',
176
+ targets: [
177
+ {
178
+ format: this.format,
179
+ blend: {
180
+ color: {
181
+ srcFactor: 'one',
182
+ dstFactor: 'one-minus-src-alpha',
183
+ operation: 'add'
184
+ },
185
+ alpha: {
186
+ srcFactor: 'one',
187
+ dstFactor: 'one-minus-src-alpha',
188
+ operation: 'add'
189
+ }
190
+ }
191
+ }
192
+ ]
193
+ },
194
+ primitive: {
195
+ topology: 'triangle-list'
196
+ }
197
+ });
198
+ this._initialized = true;
199
+ }
200
+ /**
201
+ * Configure the canvas for WebGPU rendering.
202
+ */
203
+ async setCanvas(canvas, width, height) {
204
+ await this.init();
205
+ if (!this.device) {
206
+ throw new Error('WebGPU device not initialized');
207
+ }
208
+ this._canvas = canvas;
209
+ // Get WebGPU context
210
+ if (!this.context) {
211
+ this.context = canvas.getContext('webgpu');
212
+ if (!this.context) {
213
+ throw new Error('Could not get WebGPU context');
214
+ }
215
+ this.context.configure({
216
+ device: this.device,
217
+ format: this.format,
218
+ alphaMode: 'premultiplied'
219
+ });
220
+ }
221
+ // Update canvas size
222
+ canvas.width = width;
223
+ canvas.height = height;
224
+ // Update uniform buffer with resolution
225
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([width, height]));
226
+ }
227
+ /**
228
+ * Update canvas dimensions.
229
+ */
230
+ updateSize(width, height) {
231
+ if (!this.device || !this._canvas)
232
+ return;
233
+ this._canvas.width = width;
234
+ this._canvas.height = height;
235
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([width, height]));
236
+ }
237
+ createTextureInfo(width, height) {
238
+ const texture = this.device.createTexture({
239
+ size: [width, height],
240
+ format: 'rgba8unorm',
241
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
242
+ });
243
+ return {
244
+ texture,
245
+ view: texture.createView(),
246
+ width,
247
+ height
248
+ };
249
+ }
250
+ /**
251
+ * Render subtitle compositions to the canvas.
252
+ */
253
+ render(compositions, screenWidth, screenHeight, scaleX, scaleY, offsetY) {
254
+ if (!this.device || !this.context || !this.pipeline)
255
+ return;
256
+ const commandEncoder = this.device.createCommandEncoder();
257
+ const textureView = this.context.getCurrentTexture().createView();
258
+ // Begin render pass with clear
259
+ const renderPass = commandEncoder.beginRenderPass({
260
+ colorAttachments: [
261
+ {
262
+ view: textureView,
263
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
264
+ loadOp: 'clear',
265
+ storeOp: 'store'
266
+ }
267
+ ]
268
+ });
269
+ renderPass.setPipeline(this.pipeline);
270
+ // Grow buffers if needed
271
+ while (this.textures.length < compositions.length) {
272
+ this.textures.push(this.createTextureInfo(64, 64));
273
+ }
274
+ while (this.quadDataBuffers.length < compositions.length) {
275
+ this.quadDataBuffers.push(this.device.createBuffer({
276
+ size: 32, // 2 x vec4f
277
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
278
+ }));
279
+ }
280
+ // Render each composition
281
+ for (let i = 0; i < compositions.length; i++) {
282
+ const comp = compositions[i];
283
+ const { pixelData, x, y } = comp;
284
+ const { width, height, data } = pixelData;
285
+ if (width <= 0 || height <= 0)
286
+ continue;
287
+ let texInfo = this.textures[i];
288
+ // Recreate texture if size changed
289
+ if (texInfo.width !== width || texInfo.height !== height) {
290
+ this.pendingDestroyTextures.push(texInfo.texture);
291
+ texInfo = this.createTextureInfo(width, height);
292
+ this.textures[i] = texInfo;
293
+ }
294
+ // Upload RGBA data to texture
295
+ this.device.queue.writeTexture({ texture: texInfo.texture }, data.buffer, { bytesPerRow: width * 4, offset: data.byteOffset }, { width, height });
296
+ // Calculate scaled position and size
297
+ const scaledWidth = width * scaleX;
298
+ const scaledHeight = height * scaleY;
299
+ const baseX = x * (this._canvas.width / screenWidth);
300
+ const baseY = y * (this._canvas.height / screenHeight);
301
+ const centeredX = baseX + (width * (this._canvas.width / screenWidth) - scaledWidth) / 2;
302
+ const adjustedY = baseY + offsetY + (height * (this._canvas.height / screenHeight) - scaledHeight);
303
+ // Update quad data buffer
304
+ const quadData = new Float32Array([
305
+ // destRect
306
+ centeredX,
307
+ adjustedY,
308
+ scaledWidth,
309
+ scaledHeight,
310
+ // texSize
311
+ width,
312
+ height,
313
+ 0,
314
+ 0
315
+ ]);
316
+ const quadBuffer = this.quadDataBuffers[i];
317
+ this.device.queue.writeBuffer(quadBuffer, 0, quadData);
318
+ // Create bind group for this composition
319
+ const bindGroup = this.device.createBindGroup({
320
+ layout: this.bindGroupLayout,
321
+ entries: [
322
+ { binding: 0, resource: { buffer: this.uniformBuffer } },
323
+ { binding: 1, resource: { buffer: quadBuffer } },
324
+ { binding: 2, resource: this.sampler },
325
+ { binding: 3, resource: texInfo.view }
326
+ ]
327
+ });
328
+ renderPass.setBindGroup(0, bindGroup);
329
+ renderPass.draw(6); // 6 vertices for quad
330
+ }
331
+ renderPass.end();
332
+ this.device.queue.submit([commandEncoder.finish()]);
333
+ // Destroy old textures after submit
334
+ for (const tex of this.pendingDestroyTextures) {
335
+ tex.destroy();
336
+ }
337
+ this.pendingDestroyTextures = [];
338
+ }
339
+ /**
340
+ * Clear the canvas.
341
+ */
342
+ clear() {
343
+ if (!this.device || !this.context)
344
+ return;
345
+ const commandEncoder = this.device.createCommandEncoder();
346
+ const textureView = this.context.getCurrentTexture().createView();
347
+ const renderPass = commandEncoder.beginRenderPass({
348
+ colorAttachments: [
349
+ {
350
+ view: textureView,
351
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
352
+ loadOp: 'clear',
353
+ storeOp: 'store'
354
+ }
355
+ ]
356
+ });
357
+ renderPass.end();
358
+ this.device.queue.submit([commandEncoder.finish()]);
359
+ }
360
+ /**
361
+ * Check if renderer is initialized.
362
+ */
363
+ get initialized() {
364
+ return this._initialized;
365
+ }
366
+ /**
367
+ * Destroy all resources.
368
+ */
369
+ destroy() {
370
+ for (const tex of this.textures) {
371
+ tex.texture.destroy();
372
+ }
373
+ this.textures = [];
374
+ for (const tex of this.pendingDestroyTextures) {
375
+ tex.destroy();
376
+ }
377
+ this.pendingDestroyTextures = [];
378
+ this.uniformBuffer?.destroy();
379
+ for (const buf of this.quadDataBuffers) {
380
+ buf.destroy();
381
+ }
382
+ this.quadDataBuffers = [];
383
+ this.device?.destroy();
384
+ this.device = null;
385
+ this.context = null;
386
+ this._canvas = null;
387
+ this._initialized = false;
388
+ this._initPromise = null;
389
+ }
390
+ }
391
+ //# sourceMappingURL=webgpu-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgpu-renderer.js","sourceRoot":"","sources":["../../src/ts/webgpu-renderer.ts"],"names":[],"mappings":"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"}
package/dist/wrapper.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export type { SubtitleData, SubtitleCompositionData, SubtitleDisplaySettings, VideoSubtitleOptions, VideoVobSubOptions, RenderResult, SubtitleFrame, VobSubFrame } from './ts/types';
6
6
  export { initWasm, isWasmInitialized } from './ts/wasm';
7
+ export { isWebGPUSupported } from './ts/webgpu-renderer';
7
8
  export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './ts/parsers';
8
9
  export { PgsRenderer, VobSubRenderer, type SubtitleRendererStats } from './ts/renderers';
9
10
  import { PgsRenderer as _PgsRenderer, VobSubRenderer as _VobSubRenderer } from './ts/renderers';
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAGvD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGrF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAMxF,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE9E,0CAA0C;AAC1C,eAAO,MAAM,WAAW,qBAAe,CAAA;AAEvC,6CAA6C;AAC7C,eAAO,MAAM,cAAc,wBAAkB,CAAA;AAE7C,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,+BAAyB,CAAA"}
1
+ {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAGvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGrF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAMxF,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE9E,0CAA0C;AAC1C,eAAO,MAAM,WAAW,qBAAe,CAAA;AAEvC,6CAA6C;AAC7C,eAAO,MAAM,cAAc,wBAAkB,CAAA;AAE7C,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,+BAAyB,CAAA"}
package/dist/wrapper.js CHANGED
@@ -4,6 +4,8 @@
4
4
  */
5
5
  // Re-export WASM management
6
6
  export { initWasm, isWasmInitialized } from './ts/wasm';
7
+ // Re-export WebGPU utilities
8
+ export { isWebGPUSupported } from './ts/webgpu-renderer';
7
9
  // Re-export parsers
8
10
  export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './ts/parsers';
9
11
  // Re-export renderers
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,4BAA4B;AAC5B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEvD,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAErF,sBAAsB;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAA8B,MAAM,gBAAgB,CAAA;AAExF,gFAAgF;AAChF,8CAA8C;AAC9C,gFAAgF;AAEhF,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE9E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAA;AAEvC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAA;AAE7C,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,sBAAsB,CAAA"}
1
+ {"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,4BAA4B;AAC5B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEvD,6BAA6B;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAErF,sBAAsB;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAA8B,MAAM,gBAAgB,CAAA;AAExF,gFAAgF;AAChF,8CAA8C;AAC9C,gFAAgF;AAEhF,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE9E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAA;AAEvC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAA;AAE7C,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,sBAAsB,CAAA"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "libbitsub",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "author": "altqx",
5
- "license": "GPL-3.0-only",
5
+ "license": "MIT OR Apache-2.0",
6
6
  "description": "High-performance WASM renderer for graphical subtitles (PGS and VobSub)",
7
7
  "keywords": [
8
8
  "libbitsub",
@@ -50,5 +50,8 @@
50
50
  "peerDependencies": {},
51
51
  "engines": {
52
52
  "node": ">=18"
53
+ },
54
+ "dependencies": {
55
+ "@webgpu/types": "^0.1.68"
53
56
  }
54
57
  }