wasm-webp 0.0.1-beta.1

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 nieyuyao0826@hotmail.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,239 @@
1
+ # WIP
2
+
3
+ # `webp.wasm`
4
+
5
+ webp.wasm is a pure Webassembly / Javascript port of libwebp.
6
+
7
+ ![CI](https://github.com/nieyuyao/webp-wasm/workflows/CI/badge.svg)
8
+
9
+ ## APIs
10
+
11
+ ### Encode
12
+
13
+ #### encode
14
+
15
+ Get encoder encoderVersion.
16
+
17
+ `function encoderVersion(): Promise<string>`
18
+
19
+ ##### Example
20
+
21
+ ```javascript
22
+ const version = await encoderVersion()
23
+ console.log(version) // 1.3.2
24
+ ```
25
+
26
+ #### encodeRGB
27
+
28
+ Encodes rgb bitmap an returns WebP Uint8Array. The `width` and `height` parameters of the bitmap should be provided.
29
+
30
+ `function encodeRGB(rgb: Uint8Array, width: number, height: number, quality?: number): Promise<Nullable<Uint8Array>>`
31
+
32
+ ##### Example
33
+
34
+ ```javascript
35
+ ...
36
+ const ctx = canvas.getContext('2d')!
37
+ const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
38
+ const buf = new Uint8Array(3 * canvas.width, canvas.height)
39
+ let j = 0
40
+ // remove alpha
41
+ imgData.data.forEach((pixel, i) => {
42
+ if ((i + 1) % 4 === 0) {
43
+ return
44
+ }
45
+ buf[j] = pixel
46
+ j++
47
+ })
48
+ const webpData = await encodeRGB(buf, canvas.width, canvas.height)
49
+ const blob = new Blob([webpData!], {type: 'image/webp'})
50
+ const blobURL = URL.createObjectURL(blob);
51
+ // download webp
52
+ const a = document.createElement('a')
53
+ a.download = '1.webp'
54
+ a.href = blobURL
55
+ document.body.appendChild(a)
56
+ a.click()
57
+ a.remove()
58
+ ```
59
+
60
+ #### encodeRGBA
61
+
62
+ Encodes rgba bitmap an returns WebP Uint8Array.
63
+
64
+ `function encodeRGBA(rgba: Uint8Array, width: number, height: number, quality?: number): Promise<Nullable<Uint8Array>>`
65
+
66
+ ##### Example
67
+
68
+ ```javascript
69
+ ...
70
+ const ctx = canvas.getContext('2d')!
71
+ const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
72
+ const webpData = await encodeRGBA(imgData.data, canvas.width, canvas.height)
73
+ // download webp
74
+ ...
75
+ ```
76
+
77
+ #### encode
78
+
79
+ A more advanced API is based on the WebPConfig. <b>Only the lossless and quality parameters are supported now !!!</b>. You can generate low-quality webp with this function.
80
+
81
+ `function encodeRGBA(data: Uint8Array, width: number, height: number, hasAlpha: boolean,config: Partial<WebPConfig>): Promise<Nullable<Uint8Array>>`
82
+
83
+ - hasAlpha: boolean
84
+
85
+ Whether to include alpha chanel.
86
+
87
+ - WebPConfig.lossless: number
88
+
89
+ Lossless encoding (0=lossy(default), 1=lossless).
90
+
91
+ - WebPConfig.quality: number
92
+
93
+ Between 0 and 100. Default value is 100.
94
+
95
+ ##### Example
96
+
97
+ ```javascript
98
+ ...
99
+ const ctx = canvas.getContext('2d')!
100
+ const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
101
+ const webpData = await encode(imgData.data, canvas.width, canvas.height, true, { lossless: 0 })
102
+ // download webp
103
+ ...
104
+ ```
105
+
106
+ #### encodeAnimation
107
+
108
+ Returns animated WebP like `GIF`.
109
+
110
+ `function encodeAnimation(width: number, height: number, hasAlpha: boolean, frames: WebPAnimationFrame[]): Promise<Nullable<Uint8Array>>`
111
+
112
+ - hasAlpha: boolean
113
+
114
+ Whether to include alpha chanel.
115
+
116
+ The WebPAnimationFrame has follow properties:
117
+
118
+ - WebPAnimationFrame.data: Uint8Array
119
+
120
+ Frame bitmap.
121
+
122
+ - WebPAnimationFrame.duration: number
123
+
124
+ Duration of frame.
125
+
126
+ ##### Example
127
+
128
+ ```javascript
129
+ ...
130
+ // record each frame
131
+ frames.push({
132
+ data: ctx.getImageData(0, 0, 100, 100).data,
133
+ duration: 20
134
+ })
135
+ const webpData = await encodeAnimation(100, 100, true, frames)
136
+ ...
137
+ // download webp
138
+ ```
139
+
140
+ ### Decode
141
+
142
+ #### decoderVersion
143
+
144
+ Get decoder version.
145
+
146
+ `function decoderVersion(): Promise<string>`
147
+
148
+ ##### Example
149
+
150
+ ```javascript
151
+ const version = await decoderVersion()
152
+ console.log(version) // 1.3.2
153
+ ```
154
+
155
+ #### decodeRGB
156
+
157
+ Decodes webp and outputs `WebPDecodedImageData` contains rgb bitmap.
158
+
159
+ `function decodeRGB(data: Uint8Array): Promise<Nullable<WebPDecodedImageData>>`
160
+
161
+ ##### Example
162
+
163
+ ```javascript
164
+ ...
165
+ const fr = new FileReader()
166
+ fr.onload = () => {
167
+ if (!fr.result) {
168
+ return
169
+ }
170
+ webpData = fr.result as Uint8Array
171
+ const result = await decodeRGB(webpData)
172
+ // draw imageData
173
+ const ctx = canvas.getContext('2d')!
174
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
175
+ canvas.style.width = `${result.width}px`
176
+ canvas.style.height = `${result.height}px`
177
+ canvas.width = result.width
178
+ canvas.height = result.height
179
+ ctx.putImageData(result, 0, 0)
180
+ }
181
+ // read webp file
182
+ fr.readAsArrayBuffer(file)
183
+ ...
184
+ ```
185
+
186
+ #### decodeRGBA
187
+
188
+ Decodes webp and outputs `WebPDecodedImageData` contains rgba bitmap.
189
+
190
+ `function decodeRGB(data: Uint8Array): Promise<Nullable<WebPDecodedImageData>>`
191
+
192
+ ##### Example
193
+
194
+ ```javascript
195
+ ...
196
+ const fr = new FileReader()
197
+ fr.onload = () => {
198
+ if (!fr.result) {
199
+ return
200
+ }
201
+ webpData = fr.result as Uint8Array
202
+ const result = await decodeRGBA(webpData)
203
+ // draw imageData
204
+ ...
205
+ }
206
+ // webp file
207
+ fr.readAsArrayBuffer(file)
208
+ ...
209
+ ```
210
+
211
+ #### WebPDecodedImageData
212
+
213
+ The object have the following properties:
214
+
215
+ - WebPDecodedImageData.width: number
216
+
217
+ The image width in pixels.
218
+
219
+ - WebPDecodedImageData.height: number
220
+
221
+ The image height in pixels.
222
+
223
+ - WebPDecodedImageData.data: Uint8Array
224
+
225
+ Raw data in pixels.
226
+
227
+ > Note: It looks like an `ImageData` object, but it is not. There is actually no `ImageData` in node.
228
+
229
+ ## Playing Examples
230
+
231
+ ```shell
232
+ npm run dev
233
+ ```
234
+
235
+ ## Building
236
+
237
+ ```shell
238
+ npm run build
239
+ ```
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.decodeRGBA = exports.decodeRGB = exports.decoderVersion = exports.encodeAnimation = exports.encode = exports.encodeRGBA = exports.encodeRGB = exports.encoderVersion = void 0;
16
+ // @ts-ignore
17
+ const webp_wasm_1 = __importDefault(require("./webp-wasm"));
18
+ // default webp config
19
+ const defaultWebpConfig = {
20
+ lossless: 0,
21
+ quality: 100,
22
+ };
23
+ const encoderVersion = () => __awaiter(void 0, void 0, void 0, function* () {
24
+ const module = yield (0, webp_wasm_1.default)();
25
+ return module.encoder_version();
26
+ });
27
+ exports.encoderVersion = encoderVersion;
28
+ const encodeRGB = (rgb, width, height, quality) => __awaiter(void 0, void 0, void 0, function* () {
29
+ const module = yield (0, webp_wasm_1.default)();
30
+ quality = typeof quality !== 'number' ? 100 : Math.min(Math.max(0, quality));
31
+ return module.encodeRGB(rgb, width, height, quality);
32
+ });
33
+ exports.encodeRGB = encodeRGB;
34
+ const encodeRGBA = (rgba, width, height, quality) => __awaiter(void 0, void 0, void 0, function* () {
35
+ const module = yield (0, webp_wasm_1.default)();
36
+ quality = typeof quality !== 'number' ? 100 : Math.min(Math.max(0, quality));
37
+ return module.encodeRGBA(rgba, width, height, quality);
38
+ });
39
+ exports.encodeRGBA = encodeRGBA;
40
+ const encode = (data, width, height, hasAlpha, config) => __awaiter(void 0, void 0, void 0, function* () {
41
+ const module = yield (0, webp_wasm_1.default)();
42
+ const webpConfig = Object.assign(Object.assign({}, defaultWebpConfig), config);
43
+ return module.encode(data, width, height, hasAlpha, webpConfig);
44
+ });
45
+ exports.encode = encode;
46
+ const encodeAnimation = (width, height, hasAlpha, frames) => __awaiter(void 0, void 0, void 0, function* () {
47
+ const module = yield (0, webp_wasm_1.default)();
48
+ const durations = [];
49
+ const dataLength = frames.reduce((acc, frame) => {
50
+ acc += frame.data.length;
51
+ return acc;
52
+ }, 0);
53
+ const data = new Uint8ClampedArray(dataLength);
54
+ let offset = 0;
55
+ frames.forEach(frame => {
56
+ data.set(frame.data, offset);
57
+ offset += frame.data.length;
58
+ durations.push(frame.duration);
59
+ });
60
+ return module.encodeAnimation(width, height, hasAlpha, durations, data);
61
+ });
62
+ exports.encodeAnimation = encodeAnimation;
63
+ const decoderVersion = () => __awaiter(void 0, void 0, void 0, function* () {
64
+ const module = yield (0, webp_wasm_1.default)();
65
+ return module.decoder_version();
66
+ });
67
+ exports.decoderVersion = decoderVersion;
68
+ const decodeRGB = (rgb) => __awaiter(void 0, void 0, void 0, function* () {
69
+ const module = yield (0, webp_wasm_1.default)();
70
+ return module.decodeRGB(rgb);
71
+ });
72
+ exports.decodeRGB = decodeRGB;
73
+ const decodeRGBA = (rgba) => __awaiter(void 0, void 0, void 0, function* () {
74
+ const module = yield (0, webp_wasm_1.default)();
75
+ return module.decodeRGBA(rgba);
76
+ });
77
+ exports.decodeRGBA = decodeRGBA;
78
+ // TODO:
79
+ // export const decode = async (data: Uint8ClampedArray, hasAlpha: boolean) => {
80
+ // const module = await Module()
81
+ // return module.decode(data, hasAlpha)
82
+ // }