emf-converter 4.23.1 → 4.24.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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![CI](https://github.com/ChristopherVR/emf-converter/actions/workflows/ci.yml/badge.svg)](https://github.com/ChristopherVR/emf-converter/actions/workflows/ci.yml)
5
5
  [![license](https://img.shields.io/npm/l/emf-converter.svg)](LICENSE)
6
6
 
7
- A zero-dependency TypeScript library that converts **EMF** (Enhanced Metafile, including embedded **EMF+** / GDI+ records) and **WMF** (Windows Metafile) files into **PNG**, **JPEG** or **SVG** (markup, a base64 data URL, React elements, or a generated JSX/TSX component).
7
+ A zero-dependency TypeScript library that converts **EMF** (Enhanced Metafile, including embedded **EMF+** / GDI+ records) and **WMF** (Windows Metafile) files into **PNG**, **JPEG**, **WebP**, **SVG** (markup, a base64 data URL, React elements, or a generated JSX/TSX component) or **PDF**. The input can be an `ArrayBuffer`, a typed array or Node.js `Buffer`, or a `Blob`, plain or gzip-compressed (`.emz`, `.wmz`).
8
8
 
9
9
  Windows metafiles are recorded GDI and GDI+ drawing calls, commonly embedded in Office documents and on the Windows clipboard. This library replays those calls the way Windows does: the PNG output is checked pixel for pixel against images painted by Windows itself (hundreds of ground-truth fixtures under `src/__fixtures__/gdi`, generated by `scripts/gdi-fixtures`), and the SVG output keeps vectors, text and gradients resolution-independent.
10
10
 
@@ -32,14 +32,14 @@ npm install emf-converter
32
32
 
33
33
  No required dependencies:
34
34
 
35
- - **Browser / Web Worker**: `OffscreenCanvas` or `HTMLCanvasElement` is used automatically for PNG and JPEG. Bundlers select the dedicated browser entry through conditional exports; it contains no native canvas or Node filesystem imports. Installing `@napi-rs/canvas` is only needed for the optional Node backend.
36
- - **Node.js**: SVG output, and PNG/JPEG output for drawings without text, work out of the box through the built-in rasteriser. For PNG/JPEG output of drawings with text, either pass `fonts` (see [Exact text](#exact-text)) or install the optional [`@napi-rs/canvas`](https://www.npmjs.com/package/@napi-rs/canvas) (prebuilt, no `node-gyp`):
35
+ - **Browser / Web Worker**: `OffscreenCanvas` or `HTMLCanvasElement` is used automatically for PNG, JPEG and WebP. Bundlers select the dedicated browser entry through conditional exports; it contains no native canvas or Node filesystem imports. Installing `@napi-rs/canvas` is only needed for the optional Node backend.
36
+ - **Node.js**: SVG and PDF output, and PNG/JPEG/WebP output for drawings without text, work out of the box through the built-in rasteriser. For PNG/JPEG/WebP output of drawings with text, either pass `fonts` (see [Exact text](#exact-text)) or install the optional [`@napi-rs/canvas`](https://www.npmjs.com/package/@napi-rs/canvas) (prebuilt, no `node-gyp`):
37
37
 
38
38
  ```bash
39
39
  npm install @napi-rs/canvas
40
40
  ```
41
41
 
42
- Without either, PNG/JPEG conversion of a drawing that contains text returns `null` rather than an image missing its text.
42
+ Without either, PNG/JPEG/WebP conversion of a drawing that contains text returns `null` rather than an image missing its text.
43
43
 
44
44
  ## Quick start
45
45
 
@@ -60,6 +60,20 @@ const smooth = await convertMetafileToDataUrl(buffer, { gdiAntialias: true });
60
60
 
61
61
  Returns `Promise<string | null>`; `null` when the buffer is not a valid metafile (or, in plain Node.js, when it has text and neither `fonts` nor `@napi-rs/canvas` is available).
62
62
 
63
+ For the bytes themselves, use `convertMetafile`. It takes a `format` (`'png'` by default, `'jpeg'`, `'webp'` or `'svg'`) and returns the encoded file, which is what you write to disk in Node.js:
64
+
65
+ ```typescript
66
+ import { readFile, writeFile } from 'node:fs/promises';
67
+ import { convertMetafile } from 'emf-converter';
68
+
69
+ const image = await convertMetafile(await readFile('drawing.emf'), { format: 'webp' });
70
+ if (image) {
71
+ await writeFile('drawing.webp', image.data); // image.data is a Uint8Array
72
+ }
73
+ ```
74
+
75
+ The data-URL functions are wrappers around `convertMetafile`, so both give the same image.
76
+
63
77
  ### JPEG output
64
78
 
65
79
  ```typescript
@@ -75,6 +89,20 @@ const preview = await convertMetafileToJpegDataUrl(buffer, { quality: 0.7, backg
75
89
 
76
90
  The same rendering as the PNG, encoded by the bundled baseline JPEG encoder, so the output is identical in browsers and Node.js. JPEG has no transparency: the metafile's transparent background is filled with `background`. Colour is kept at full resolution (4:4:4) so coloured lines and text stay crisp; `chromaSubsampling: true` halves it (4:2:0) for a smaller file.
77
91
 
92
+ ### WebP output
93
+
94
+ ```typescript
95
+ import { convertMetafileToWebpDataUrl } from 'emf-converter';
96
+
97
+ const webp = await convertMetafileToWebpDataUrl(buffer);
98
+ // => "data:image/webp;base64,UklGR..."
99
+
100
+ // Lossy WebP at quality 0-1 (default 0.8), plus every PNG option (maxWidth, dpiScale, fonts, ...).
101
+ const small = await convertMetafileToWebpDataUrl(buffer, { lossless: false, quality: 0.8, maxWidth: 800 });
102
+ ```
103
+
104
+ The same rendering as the PNG, encoded by the bundled WebP encoder, so the output is identical in browsers and Node.js. The default is lossless: the pixels and the transparent background are kept exactly, and the file is usually smaller than the PNG. Lossy WebP (`lossless: false`) comes from a simple encoder. For line art and text it is usually much larger than lossless, so use it only for smooth, photo-like content. Images larger than 16383 pixels on a side return `null`.
105
+
78
106
  ### SVG output
79
107
 
80
108
  ```typescript
@@ -147,13 +175,151 @@ const png = await convertMetafileToDataUrl(buffer, { fonts });
147
175
 
148
176
  Without `fonts`, text is drawn by the host's canvas font engine (supply `fontFamilyMap` to remap Windows face names). SVG output always keeps text as `<text>`; with `fonts` it carries GDI's exact per-glyph positions.
149
177
 
178
+ ### PDF output
179
+
180
+ ```typescript
181
+ import { convertMetafileToPdf, loadSystemFonts } from 'emf-converter';
182
+
183
+ const fonts = await loadSystemFonts(); // Node.js only
184
+ const pdf = await convertMetafileToPdf(buffer, { fonts, title: 'Drawing' });
185
+ // => Uint8Array holding a PDF file, or null
186
+ ```
187
+
188
+ The output is a one-page vector PDF 1.7. It uses the same replay as the SVG output, so paths, clipping, gradients, patterns, opacity, blend modes and images are kept as vectors or embedded (JPEG bytes are copied unchanged). The page is the drawing itself by default (1 pixel = 0.75 pt); `pageSize: { width, height }` in points fits it to a page instead.
189
+
190
+ Text is real text. With `fonts`, the matching TrueType face is embedded as a subset, so the text is selectable and searchable. Without `fonts`, text uses the standard PDF fonts (Helvetica, Times or Courier) and looks different from the original font. The output does not include PDF/A or tagged PDF. It has been checked with pdf.js.
191
+
192
+ ### Raw RGBA pixels
193
+
194
+ ```typescript
195
+ import { convertMetafileToImageData } from 'emf-converter';
196
+
197
+ const image = await convertMetafileToImageData(buffer);
198
+ if (image) {
199
+ const { data, width, height } = image; // straight (non-premultiplied) RGBA, row-major, top-down
200
+ // e.g. sharp(data, { raw: { width, height, channels: 4 } }).png().toFile('drawing.png');
201
+ }
202
+ ```
203
+
204
+ This is the same rendering the PNG output encodes, without the encoding step, for code that needs the pixels themselves.
205
+
206
+ ### Inspecting a file
207
+
208
+ `getMetafileInfo` reads the header and records without rendering anything, so you can see what a file contains before converting it:
209
+
210
+ ```typescript
211
+ import { getMetafileInfo } from 'emf-converter';
212
+
213
+ const info = await getMetafileInfo(buffer);
214
+ // info.format: 'emf' | 'emf+' | 'emf+dual' | 'wmf'
215
+ // info.width, info.height: the PNG size at default options
216
+ // info.fonts: [{ name: 'Segoe UI', gdi: true, emfPlus: false }, ...]
217
+ ```
218
+
219
+ The main use is finding out which font files to pass as `fonts`: `info.fonts` lists the face names the file declares, so you know which fonts to supply for exact text. The list is of declared fonts, and not every one is necessarily drawn with. Fonts inside nested WMFs are not collected. The `width` and `height` ignore `maxWidth` and `dpiScale`. See the [API reference](docs/api.md) for every field.
220
+
221
+ ### Cancellation
222
+
223
+ Every conversion function accepts `signal` (an `AbortSignal`) and `timeoutMs`:
224
+
225
+ ```typescript
226
+ const controller = new AbortController();
227
+ const timer = setTimeout(() => controller.abort(), 5000);
228
+ try {
229
+ const png = await convertMetafileToDataUrl(buffer, { signal: controller.signal });
230
+ } finally {
231
+ clearTimeout(timer);
232
+ }
233
+
234
+ // Or reject after a time limit, with a DOMException named TimeoutError.
235
+ const quick = await convertMetafileToDataUrl(buffer, { timeoutMs: 5000 });
236
+ ```
237
+
238
+ When the signal aborts, the promise rejects with `signal.reason` (an `AbortError` when there is none). A `null` result still means the buffer is not a valid metafile. Conversion checks the signal at every record, so it stops within about one record's work. One very large record, such as a single giant blit, can overrun the limit. With a `signal`, conversion yields to the event loop about every 16 ms.
239
+
240
+ ### Command line
241
+
242
+ The package installs an `emf-converter` command, which `npx emf-converter` runs:
243
+
244
+ ```text
245
+ Usage: emf-converter <files...> [options]
246
+
247
+ Convert EMF, EMF+, WMF and gzip-compressed (.emz, .wmz) metafiles to PNG,
248
+ JPEG, WebP, SVG or PDF.
249
+
250
+ Inputs:
251
+ <files...> Files to convert. "-" reads one file from stdin.
252
+ Wildcards (* and ?) are expanded by the CLI itself.
253
+
254
+ Options:
255
+ -f, --format <fmt> Output format: png, jpeg, webp, svg or pdf. Default:
256
+ from the --out extension, else png.
257
+ -o, --out <path> Output file for one input, or a directory (created if
258
+ missing) for several. Default: next to each input,
259
+ with the new extension. "-" writes to stdout.
260
+ Stdin input without --out also writes to stdout.
261
+ --width <px> Maximum output width in pixels.
262
+ --height <px> Maximum output height in pixels.
263
+ --scale <n> DPI scale factor (default 1; the library clamps to 4).
264
+ --quality <0-1> JPEG quality (default 0.92), or lossy WebP quality
265
+ (default 0.8).
266
+ --lossy Lossy WebP instead of the default lossless WebP.
267
+ --background <c> JPEG colour under transparent areas, #rgb or #rrggbb
268
+ (default #ffffff). JPEG only.
269
+ --antialias Smooth shape edges instead of reproducing Windows'
270
+ own rasterisation.
271
+ --fonts <value> "system" (default): the installed fonts, so text
272
+ matches Windows; "none": no font files; or a
273
+ directory of .ttf, .ttc, .fon or .fnt files.
274
+ -q, --quiet Print only errors.
275
+ -h, --help Show this help.
276
+ -v, --version Print the version.
277
+
278
+ Exit codes: 0 all files converted, 1 one or more files failed (the rest are
279
+ still converted), 2 usage error.
280
+
281
+ Examples:
282
+ emf-converter drawing.emf
283
+ emf-converter drawing.emf --width 1200 -o drawing.jpg
284
+ emf-converter "charts/*.wmf" -f svg -o out/
285
+ cat drawing.emz | emf-converter - -f png > drawing.png
286
+ ```
287
+
288
+ The `--fonts system` default loads the installed fonts, so text matches Windows. Wildcards are expanded by the CLI itself (Node.js 22 or later), and a file named explicitly is converted whatever its extension.
289
+
150
290
  ## API
151
291
 
292
+ ### `MetafileInput`
293
+
294
+ ```ts
295
+ type MetafileInput = ArrayBuffer | ArrayBufferView | Blob;
296
+ ```
297
+
298
+ Every conversion function accepts this. Typed arrays, `DataView`s and Node.js `Buffer`s are read from their viewed bytes only, so pass the `Buffer` itself. Gzip-compressed `.emz` and `.wmz` files are inflated automatically (needs `DecompressionStream`: browsers and Node.js 18+; inflated size is capped at 256 MiB).
299
+
300
+ ### `convertMetafile(input, options?)`
301
+
302
+ | Parameter | Type | Description |
303
+ | ----------- | ------------------------------ | ----------------------------------------------------------------- |
304
+ | `input` | `MetafileInput` | Raw EMF or WMF file (format is auto-detected) |
305
+ | `options` | `ConvertOptions` (optional) | `format` (`'png'` default, `'jpeg'`, `'webp'`, `'svg'`) plus that format's options |
306
+ | **Returns** | `Promise<ConvertedImage \| null>` | The encoded file, or `null` on failure |
307
+
308
+ #### `ConvertedImage`
309
+
310
+ | Field | Type | Description |
311
+ | ---------- | ------------ | ----------- |
312
+ | `format` | `'png' \| 'jpeg' \| 'webp' \| 'svg'` | The output format |
313
+ | `mimeType` | `string` | `image/png`, `image/jpeg`, `image/webp` or `image/svg+xml` |
314
+ | `data` | `Uint8Array` | The file bytes |
315
+ | `width` | `number` | Pixel width, or the SVG's `width` |
316
+ | `height` | `number` | Pixel height, or the SVG's `height` |
317
+
152
318
  ### `convertMetafileToDataUrl(buffer, options?)`
153
319
 
154
320
  | Parameter | Type | Description |
155
321
  | ----------- | ------------------------------ | --------------------------------------------------- |
156
- | `buffer` | `ArrayBuffer` | Raw EMF or WMF file bytes (format is auto-detected) |
322
+ | `buffer` | `MetafileInput` | Raw EMF or WMF file (format is auto-detected) |
157
323
  | `options` | `EmfConvertOptions` (optional) | See below |
158
324
  | **Returns** | `Promise<string \| null>` | PNG data URL, or `null` on failure |
159
325
 
@@ -180,6 +346,8 @@ page. The defaults are `1252` and `437`; explicit text charsets are unchanged.
180
346
  | `fonts` | `Array<ArrayBuffer \| ArrayBufferView>` | None | TrueType (`.ttf`/`.ttc`) and raster (`.fon`/`.fnt`) font files for exact GDI text |
181
347
  | `fontSmoothing` | `'cleartype' \| 'gray' \| 'mono'` | `'cleartype'` | What `DEFAULT_QUALITY` / `DRAFT_QUALITY` / `PROOF_QUALITY` fonts render as (Windows' system setting) |
182
348
  | `fontFamilyMap` | `Record<string, string>` | None | Without `fonts`: maps Windows face names (case-insensitive) to locally available fonts, e.g. `{ calibri: 'Carlito' }` |
349
+ | `signal` | `AbortSignal` | None | Cancels the conversion: the promise rejects with `signal.reason` when it aborts (see [Cancellation](#cancellation)) |
350
+ | `timeoutMs` | `number` | None | Rejects with a `DOMException` named `TimeoutError` after this many milliseconds |
183
351
 
184
352
  ### `convertMetafileToJpegDataUrl(buffer, options?)`
185
353
 
@@ -214,13 +382,85 @@ Returns `Promise<string | null>`, a `data:image/jpeg;base64,...` URL (`null` in
214
382
  | `includeSize` | `boolean` | `true` | Emit `width`/`height` on the root `<svg>` (`viewBox` is always emitted); `false` gives a fluid SVG |
215
383
  | `idPrefix` | `string` | `emf1-`, `emf2-`, ... | Prefix for generated element ids; keep it unique per inlined SVG |
216
384
 
385
+ ### `convertMetafileToWebpDataUrl(buffer, options?)`
386
+
387
+ Returns `Promise<string | null>`, a `data:image/webp;base64,...` URL (`null` in the same cases as the PNG function, and for images larger than 16383 pixels on a side).
388
+
389
+ #### `WebpConvertOptions` (extends `EmfConvertOptions`)
390
+
391
+ | Field | Type | Default | Description |
392
+ | --- | --- | --- | --- |
393
+ | `lossless` | `boolean` | `true` | `true` writes lossless WebP: exact pixels, transparency kept. `false` writes lossy WebP at `quality` (transparency is still kept). |
394
+ | `quality` | `number` | `0.8` | Lossy quality from `0` to `1`. Ignored when `lossless` is `true`. |
395
+
396
+ ### `convertMetafileToPdf(buffer, options?)`
397
+
398
+ ```ts
399
+ function convertMetafileToPdf(buffer: MetafileInput, options?: PdfConvertOptions): Promise<Uint8Array | null>;
400
+ ```
401
+
402
+ Returns the bytes of a one-page vector PDF, or `null` for an invalid or empty metafile. `svgTreeToPdf(tree, options?)` makes the same PDF from an `SvgNode` tree.
403
+
404
+ #### `PdfConvertOptions` (extends `SvgConvertOptions`, plus `PdfOptions`)
405
+
406
+ | Field | Type | Default | Description |
407
+ | --- | --- | --- | --- |
408
+ | `pageSize` | `'drawing' \| { width: number; height: number }` | `'drawing'` | `'drawing'` makes the page the drawing itself (1 pixel = 0.75 pt). `{ width, height }` in points fits the drawing to a page of that size, centred. |
409
+ | `fonts` | `Array<ArrayBuffer \| ArrayBufferView>` | None | TrueType (`.ttf`, `.ttc`) files. Text in a matching font is embedded as a subset of that face. Other text uses the standard PDF fonts. |
410
+ | `compress` | `boolean` | `true` | Deflate the content streams and image data. |
411
+ | `title` | `string` | None | Document title in the PDF information dictionary. |
412
+ | `decodeImage` | `(bytes: Uint8Array, mime: string) => PdfDecodedImage \| null` (may be async) | None | Decodes an embedded image format that is neither JPEG nor handled by the bundled decoders (PNG, BMP, GIF, TIFF, WebP). Returns straight RGBA, or `null` to skip the image. |
413
+
414
+ ### `convertMetafileToImageData(buffer, options?)`
415
+
416
+ ```ts
417
+ function convertMetafileToImageData(buffer: MetafileInput, options?: EmfConvertOptions): Promise<RgbaImage | null>;
418
+ ```
419
+
420
+ Returns `{ data: Uint8ClampedArray, width, height }`: straight (non-premultiplied) RGBA, row-major and top-down, like `ImageData`. It is the rendering the PNG output encodes, without the encoding step.
421
+
422
+ ### `getMetafileInfo(buffer, options?)`
423
+
424
+ ```ts
425
+ function getMetafileInfo(buffer: MetafileInput, options?: MetafileInfoOptions): Promise<MetafileInfo | null>;
426
+ ```
427
+
428
+ Reads the header and records without rendering, and returns `null` for an invalid metafile.
429
+
430
+ #### `MetafileInfoOptions`
431
+
432
+ | Option | Type | Default | Description |
433
+ | --- | --- | --- | --- |
434
+ | `maxRecords` | `number` | As for the converters | Record limit per stream. |
435
+ | `ansiCodePage` | `number` | `1252` | ANSI code page for WMF face names, as for the converters. |
436
+
437
+ #### `MetafileInfo`
438
+
439
+ | Field | Type | Description |
440
+ | --- | --- | --- |
441
+ | `format` | `'emf' \| 'emf+' \| 'emf+dual' \| 'wmf'` | `'emf+'` is EMF+ only (the GDI records are a stub); `'emf+dual'` has a GDI fallback. |
442
+ | `bounds` | `MetafileRect` | EMF: the header's device-pixel bounds (inclusive). WMF: the bounding box in logical units. |
443
+ | `frame` | `MetafileRect \| null` | EMF: the picture frame in .01 mm. Placeable WMF: the bounding box in .01 mm. |
444
+ | `device` | `{ width, height } \| null` | EMF: the reference device size in pixels. |
445
+ | `dpi` | `{ x, y }` | Reference device resolution (96 when unknown). |
446
+ | `width` / `height` | `number` | Pixel size `convertMetafileToDataUrl` produces at default options. |
447
+ | `recordCount` | `number` | Records read from the stream. |
448
+ | `emfPlusRecordCount` | `number` | Records read from the EMF+ streams inside `EMR_COMMENT` records. |
449
+ | `recordTypes` | `Record<string, number>` | Count by record name (`EMR_*`, `META_*`, `EMFPLUS_*`). |
450
+ | `fonts` | `MetafileFont[]` | Declared font faces: `{ name, gdi, emfPlus }`. Not every one is necessarily drawn with. |
451
+ | `hasText` | `boolean` | `true` when any text-drawing record is present. |
452
+ | `images` | `{ count, mimeTypes }` | Embedded images, including DIBs, EMF+ images and nested metafiles. |
453
+ | `embeddedMetafiles` | `number` | Nested metafiles among `images`. |
454
+ | `description` | `string \| null` | The EMF header's application and document names. |
455
+ | `truncated` | `boolean` | `true` when the record limit was hit or the stream ends in a damaged record. |
456
+
217
457
  ### `loadSystemFonts(options?)`
218
458
 
219
459
  Node.js only (returns `[]` elsewhere; the package stays browser-safe). Reads the installed `.ttf`, `.ttc`, `.fon` and `.fnt` files from the platform font folders (Windows, Linux, macOS, and per-user folders) for the `fonts` option. Options: `dirs` (scan these instead), `filter(path, name)`, `maxDepth`.
220
460
 
221
461
  ## How it works
222
462
 
223
- A three-phase pipeline: **parse → replay → export**. Records are replayed by the GDI, EMF+ or WMF handlers onto a Canvas (or the built-in pure-JavaScript rasteriser) for PNG and JPEG, or onto a recording context for SVG. GDI and GDI+ shapes, raster operations, brushes, clipping, text and WMF playback are all fitted to output painted by Windows itself.
463
+ A three-phase pipeline: **parse → replay → export**. Records are replayed by the GDI, EMF+ or WMF handlers onto a Canvas (or the built-in pure-JavaScript rasteriser) for PNG, JPEG and WebP, or onto a recording context for SVG and PDF. GDI and GDI+ shapes, raster operations, brushes, clipping, text and WMF playback are all fitted to output painted by Windows itself.
224
464
 
225
465
  See [How it works](docs/how-it-works.md) for the pipeline, the Windows-parity details and the full list of supported records.
226
466
 
@@ -131,6 +131,54 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
131
131
  THE SOFTWARE.
132
132
 
133
133
 
134
+ ===== libwebp (src/webp-decoder.ts, src/webp-vp8.ts, src/webp-vp8l.ts, src/webp-tables.ts) =====
135
+
136
+ The WebP decoder is a TypeScript port of the decoding paths of libwebp
137
+ (https://chromium.googlesource.com/webm/libwebp): the VP8 key-frame decoder
138
+ (prediction, transforms, loop filter, fancy upsampling and YUV conversion with
139
+ libwebp's fixed-point arithmetic), the VP8L lossless decoder and the ALPH
140
+ unfiltering. The constant tables in src/webp-tables.ts are copied from
141
+ libwebp's src/dec/tree_dec.c and src/dec/quant_dec.c.
142
+
143
+ Copyright (c) 2010, Google Inc. All rights reserved.
144
+
145
+ Redistribution and use in source and binary forms, with or without
146
+ modification, are permitted provided that the following conditions are
147
+ met:
148
+
149
+ * Redistributions of source code must retain the above copyright
150
+ notice, this list of conditions and the following disclaimer.
151
+
152
+ * Redistributions in binary form must reproduce the above copyright
153
+ notice, this list of conditions and the following disclaimer in
154
+ the documentation and/or other materials provided with the
155
+ distribution.
156
+
157
+ * Neither the name of Google nor the names of its contributors may
158
+ be used to endorse or promote products derived from this software
159
+ without specific prior written permission.
160
+
161
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
163
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
164
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
165
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
166
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
167
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
168
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
169
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
170
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
171
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
172
+
173
+
174
+ ===== WebP test images (src/__fixtures__/webp, repository only) =====
175
+
176
+ The .webp files were encoded from synthetic pictures drawn by a script (no
177
+ third-party image content) with libwebp 1.6.0 through Pillow, and each .png is
178
+ the same file decoded by libwebp, used as the expected output. Nothing from
179
+ them is shipped in the package.
180
+
181
+
134
182
  ===== Independent JPEG Group software (src/jpeg-arith.ts, src/jpeg-turbo.ts) =====
135
183
 
136
184
  src/jpeg-arith.ts decodes arithmetic-coded JPEG and is a port of the entropy
@@ -233,6 +281,46 @@ identification and copyright information removed and shall not be
233
281
  misrepresented as the original profile.
234
282
 
235
283
 
284
+ ===== libwebp / RFC 6386 (src/webp-vp8-tables.ts, src/webp-vp8-encoder.ts) =====
285
+
286
+ The WebP lossy encoder (src/webp-vp8-encoder.ts) follows the VP8 specification
287
+ (RFC 6386) and libwebp for the 4x4 transforms, the quantiser mapping, the frame
288
+ edge conventions and the token coding. src/webp-vp8-tables.ts holds the VP8
289
+ constant tables (default token probabilities, token probability update
290
+ probabilities, DC and AC quantiser steps), which are normative parts of the
291
+ format and are identical in the RFC and in libwebp. The lossless encoder
292
+ (src/webp-lossless.ts) is written from the public WebP Lossless Bitstream
293
+ Specification, and uses its 120-entry distance-neighbourhood table.
294
+
295
+ libwebp is distributed under the following licence:
296
+
297
+ Copyright (c) 2010, Google Inc. All rights reserved.
298
+
299
+ Redistribution and use in source and binary forms, with or without
300
+ modification, are permitted provided that the following conditions are met:
301
+
302
+ * Redistributions of source code must retain the above copyright notice, this
303
+ list of conditions and the following disclaimer.
304
+
305
+ * Redistributions in binary form must reproduce the above copyright notice,
306
+ this list of conditions and the following disclaimer in the documentation
307
+ and/or other materials provided with the distribution.
308
+
309
+ * Neither the name of Google nor the names of its contributors may be used to
310
+ endorse or promote products derived from this software without specific
311
+ prior written permission.
312
+
313
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
314
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
315
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
316
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
317
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
318
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
319
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
320
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
321
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
322
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
323
+
236
324
  ===== Measured Windows data and cited references (no third-party code) =====
237
325
 
238
326
  src/jpeg-cmyk-data.ts, src/emf-gdi-illuminant-data.ts, src/emf-plus-image-curves.ts,