mirror of
				https://github.com/1disk/edp445.git
				synced 2024-08-14 22:47:02 +00:00 
			
		
		
		
	Changed alot of things.
This commit is contained in:
		
							parent
							
								
									a5a0523e5a
								
							
						
					
					
						commit
						3513d5390c
					
				
					 2016 changed files with 336930 additions and 9 deletions
				
			
		
							
								
								
									
										16
									
								
								node_modules/@skyra/gifenc/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								node_modules/@skyra/gifenc/CHANGELOG.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| # Changelog | ||||
| 
 | ||||
| All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. | ||||
| 
 | ||||
| ### [1.0.1](https://github.com/skyra-project/gifenc/compare/v1.0.0...v1.0.1) (2022-10-29) | ||||
| 
 | ||||
| 
 | ||||
| ### Bug Fixes | ||||
| 
 | ||||
| * NodeNext moduleResolution ([#158](https://github.com/skyra-project/gifenc/issues/158)) ([119a318](https://github.com/skyra-project/gifenc/commit/119a3189a4e0af47262062cc5c7a20bd2bc509d4)) | ||||
| 
 | ||||
| ## 1.0.0 (2021-07-27) | ||||
| 
 | ||||
| ### Features | ||||
| 
 | ||||
| -   implementation ([#1](https://github.com/skyra-project/gifenc/issues/1)) ([b96df46](https://github.com/skyra-project/gifenc/commit/b96df463fe8e311174425d167515aedf60c37a64)) | ||||
							
								
								
									
										24
									
								
								node_modules/@skyra/gifenc/LICENSE.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								node_modules/@skyra/gifenc/LICENSE.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| # The MIT License (MIT) | ||||
| 
 | ||||
| Copyright © `2021` `Skyra Project` | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person | ||||
| obtaining a copy of this software and associated documentation | ||||
| files (the “Software”), to deal in the Software without | ||||
| restriction, including without limitation the rights to use, | ||||
| copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the | ||||
| Software is furnished to do so, subject to the following | ||||
| conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be | ||||
| included in all copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||||
| OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||||
| HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||||
| WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||||
| OTHER DEALINGS IN THE SOFTWARE. | ||||
							
								
								
									
										159
									
								
								node_modules/@skyra/gifenc/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								node_modules/@skyra/gifenc/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,159 @@ | |||
| <div align="center"> | ||||
| 
 | ||||
| # @skyra/gifenc | ||||
| 
 | ||||
| **A very fast server-side animated GIF generation for Node.js** | ||||
| 
 | ||||
| [](https://github.com/skyra-project/gifenc/blob/main/LICENSE.md) | ||||
| 
 | ||||
| [](https://www.npmjs.com/package/@skyra/gifenc) | ||||
|  | ||||
|  | ||||
| 
 | ||||
| [](https://join.skyra.pw) | ||||
| 
 | ||||
| </div> | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ## Features | ||||
| 
 | ||||
| -   @skyra/gifenc is a GIF encoding utility library to build your next GIFs. | ||||
| -   Supports CommonJS and ES Module. | ||||
| -   Heavily based on [`gifencoder`](https://github.com/eugeneware/gifencoder), this module wouldn't have existed without its author. | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| You can use the following command to install this package, or replace `npm install` with your package manager of choice. | ||||
| 
 | ||||
| ```sh | ||||
| npm install @skyra/gifenc | ||||
| ``` | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| > `@skyra/gifenc` is very close to a drop-in replacement for [`gifencoder`](https://www.npmjs.com/package/gifencoder). There are only 2 differences to account for. First of all, the encoder class is named `GifEncoder` and not `GIFEncoder`, and secondly, the metadata methods are chainable. | ||||
| 
 | ||||
| ### Streaming API - Writing to a file | ||||
| 
 | ||||
| ```js | ||||
| const { GifEncoder } = require('@skyra/gifenc'); | ||||
| const { createWriteStream } = require('node:fs'); | ||||
| 
 | ||||
| const encoder = new GifEncoder(400, 400); | ||||
| 	// Set the repeat mode: 0 for repeat, -1 for no-repeat: | ||||
| 	.setRepeat(0) | ||||
| 	// Set the frame delay in milliseconds: | ||||
| 	.setDelay(500) | ||||
| 	// Set the image quality, 10 is default: | ||||
| 	.setQuality(10); | ||||
| 
 | ||||
| // Create a read stream and pipe it into a file write stream: | ||||
| encoder.createReadStream() | ||||
| 	.pipe(createWriteStream('my-file.gif')); | ||||
| 
 | ||||
| encoder.start(); | ||||
| 
 | ||||
| // `getFrames` enumerates over frames | ||||
| for (const frame of getFrames()) { | ||||
| 	encoder.addFrame(frame); | ||||
| } | ||||
| 
 | ||||
| encoder.finish(); | ||||
| ``` | ||||
| 
 | ||||
| ### Streaming API - Get resulting Buffer | ||||
| 
 | ||||
| We can use [`streamConsumers.buffer()`](https://nodejs.org/dist/latest-v16.x/docs/api/webstreams.html#streamconsumersbufferstream) from Node.js to convert the stream into a buffer starting with Node.js v16.7.0, if you're using an older version, consider making a function using stream's async iterator (Node.js v10+) or use a package. | ||||
| 
 | ||||
| ```js | ||||
| const { GifEncoder } = require('@skyra/gifenc'); | ||||
| const { buffer } = require('node:stream/consumers'); | ||||
| 
 | ||||
| const encoder = new GifEncoder(400, 400); | ||||
| 
 | ||||
| const stream = encoder.createReadStream(); | ||||
| encoder.setRepeat(0).setDelay(500).setQuality(10).start(); | ||||
| 
 | ||||
| // `getFrames` enumerates over frames | ||||
| for (const frame of getFrames()) { | ||||
| 	encoder.addFrame(frame); | ||||
| } | ||||
| 
 | ||||
| encoder.finish(); | ||||
| const result = await buffer(stream); | ||||
| ``` | ||||
| 
 | ||||
| ### Using with canvas-constructor | ||||
| 
 | ||||
| ```js | ||||
| const { GifEncoder } = require('@skyra/gifenc'); | ||||
| const { Canvas } = require('canvas-constructor/skia'); | ||||
| // const { Canvas } = require('canvas-constructor/cairo'); | ||||
| 
 | ||||
| const canvas = new Canvas(400, 400); | ||||
| const encoder = new GifEncoder(400, 400); | ||||
| 
 | ||||
| const stream = encoder.createReadStream(); | ||||
| encoder.setRepeat(0).setDelay(500).setQuality(10).start(); | ||||
| 
 | ||||
| const colors = ['#98DDCA', '#D5ECC2', '#FFD3B4', '#FFAAA7']; | ||||
| for (const color of colors) { | ||||
| 	canvas.setColor(color).printRectangle(0, 0, 400, 400); | ||||
| 	encoder.addFrame(canvas); | ||||
| } | ||||
| 
 | ||||
| // ... | ||||
| ``` | ||||
| 
 | ||||
| ### Using with ECMAScript Modules | ||||
| 
 | ||||
| `@skyra/gifenc` supports ESM out of the box. To import the `GifEncoder` class, you use the following statement: | ||||
| 
 | ||||
| ```ts | ||||
| import { GifEncoder } from '@skyra/gifenc'; | ||||
| ``` | ||||
| 
 | ||||
| ## Buy us some doughnuts | ||||
| 
 | ||||
| Skyra Project is open source and always will be, even if we don't get donations. That said, we know there are amazing people who | ||||
| may still want to donate just to show their appreciation. Thanks you very much in advance! | ||||
| 
 | ||||
| We accept donations through Patreon, BitCoin, Ethereum, and Litecoin. You can use the buttons below to donate through your method of choice. | ||||
| 
 | ||||
| | Donate With |         QR         |                                                                  Address                                                                  | | ||||
| | :---------: | :----------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | | ||||
| |   Patreon   | ![PatreonImage][]  |                                               [Click Here](https://www.patreon.com/kyranet)                                               | | ||||
| |   PayPal    |  ![PayPalImage][]  |                     [Click Here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CET28NRZTDQ8L)                      | | ||||
| |   BitCoin   | ![BitcoinImage][]  |         [3JNzCHMTFtxYFWBnVtDM9Tt34zFbKvdwco](bitcoin:3JNzCHMTFtxYFWBnVtDM9Tt34zFbKvdwco?amount=0.01&label=Skyra%20Discord%20Bot)          | | ||||
| |  Ethereum   | ![EthereumImage][] | [0xcB5EDB76Bc9E389514F905D9680589004C00190c](ethereum:0xcB5EDB76Bc9E389514F905D9680589004C00190c?amount=0.01&label=Skyra%20Discord%20Bot) | | ||||
| |  Litecoin   | ![LitecoinImage][] |         [MNVT1keYGMfGp7vWmcYjCS8ntU8LNvjnqM](litecoin:MNVT1keYGMfGp7vWmcYjCS8ntU8LNvjnqM?amount=0.01&label=Skyra%20Discord%20Bot)         | | ||||
| 
 | ||||
| ## Contributors ✨ | ||||
| 
 | ||||
| Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||||
| 
 | ||||
| <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||||
| <!-- prettier-ignore-start --> | ||||
| <!-- markdownlint-disable --> | ||||
| <table> | ||||
|   <tr> | ||||
|     <td align="center"><a href="https://github.com/kyranet"><img src="https://avatars0.githubusercontent.com/u/24852502?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antonio Román</b></sub></a><br /><a href="https://github.com/skyra-project/gifenc/commits?author=kyranet" title="Code">💻</a> <a href="#ideas-kyranet" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-kyranet" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td> | ||||
|     <td align="center"><a href="https://favware.tech/"><img src="https://avatars.githubusercontent.com/u/4019718?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeroen Claassens</b></sub></a><br /><a href="#infra-Favna" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-Favna" title="Maintenance">🚧</a></td> | ||||
|   </tr> | ||||
| </table> | ||||
| 
 | ||||
| <!-- markdownlint-restore --> | ||||
| <!-- prettier-ignore-end --> | ||||
| 
 | ||||
| <!-- ALL-CONTRIBUTORS-LIST:END --> | ||||
| 
 | ||||
| This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! | ||||
| 
 | ||||
| <!-- LINK DUMP --> | ||||
| 
 | ||||
| [patreonimage]: https://cdn.skyra.pw/gh-assets/patreon.png | ||||
| [paypalimage]: https://cdn.skyra.pw/gh-assets/paypal.png | ||||
| [bitcoinimage]: https://cdn.skyra.pw/gh-assets/bitcoin.png | ||||
| [ethereumimage]: https://cdn.skyra.pw/gh-assets/ethereum.png | ||||
| [litecoinimage]: https://cdn.skyra.pw/gh-assets/litecoin.png | ||||
							
								
								
									
										3
									
								
								node_modules/@skyra/gifenc/dist/index.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								node_modules/@skyra/gifenc/dist/index.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| export * from './lib/GifEncoder'; | ||||
| export { GifEncoder as JiffEncoder } from './lib/GifEncoder'; | ||||
| //# sourceMappingURL=index.d.ts.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/index.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/index.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC"} | ||||
							
								
								
									
										8
									
								
								node_modules/@skyra/gifenc/dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								node_modules/@skyra/gifenc/dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.JiffEncoder = void 0; | ||||
| const tslib_1 = require("tslib"); | ||||
| tslib_1.__exportStar(require("./lib/GifEncoder"), exports); | ||||
| var GifEncoder_1 = require("./lib/GifEncoder"); | ||||
| Object.defineProperty(exports, "JiffEncoder", { enumerable: true, get: function () { return GifEncoder_1.GifEncoder; } }); | ||||
| //# sourceMappingURL=index.js.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/index.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/index.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,2DAAiC;AACjC,+CAA6D;AAApD,yGAAA,UAAU,OAAe"} | ||||
							
								
								
									
										5
									
								
								node_modules/@skyra/gifenc/dist/index.mjs
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								node_modules/@skyra/gifenc/dist/index.mjs
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| import mod from "./index.js"; | ||||
| 
 | ||||
| export default mod; | ||||
| export const GifEncoder = mod.GifEncoder; | ||||
| export const JiffEncoder = mod.JiffEncoder; | ||||
							
								
								
									
										51
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| /// <reference types="node" />
 | ||||
| export declare class ByteBuffer { | ||||
|     private written; | ||||
|     private data; | ||||
|     /** | ||||
|      * Constructs the instance. | ||||
|      * @param size The amount of bytes to reserve, defaults to 8KB. | ||||
|      */ | ||||
|     constructor(size?: number); | ||||
|     /** | ||||
|      * Gets the written data. | ||||
|      */ | ||||
|     get length(): number; | ||||
|     /** | ||||
|      * Resets the data. | ||||
|      * @note This does not de-allocate the data, instead, it sets the {@link ByteBuffer.written position} to zero. | ||||
|      */ | ||||
|     reset(): void; | ||||
|     /** | ||||
|      * Writes a single byte into the buffer. | ||||
|      * @param byte The byte to write, between `0x00` and `0xFF`. | ||||
|      */ | ||||
|     writeByte(byte: number): void; | ||||
|     /** | ||||
|      * Writes the `byte` value `times` times. | ||||
|      * @param byte The byte to write `times` times. | ||||
|      * @param times The amount of times to write the `byte`. | ||||
|      */ | ||||
|     writeTimes(byte: number, times: number): void; | ||||
|     /** | ||||
|      * Writes `bytes` into the data. | ||||
|      * @param bytes The bytes to write. | ||||
|      */ | ||||
|     writeBytes(bytes: ArrayLike<number>, start?: number, end?: number): void; | ||||
|     /** | ||||
|      * Gets a sub-array of what was written so far. | ||||
|      * @returns The written section of the data. | ||||
|      */ | ||||
|     toArray(): Buffer; | ||||
|     /** | ||||
|      * Fills the data with the `byte` value given a range. | ||||
|      * @param byte The value to write. | ||||
|      * @param start The start index, defaults to `0`. | ||||
|      * @param end The end index, defaults to {@link Uint8Array.length `this.data.length`}. | ||||
|      */ | ||||
|     fill(byte: number, start?: number, end?: number): void; | ||||
|     private ensureByte; | ||||
|     private ensureBytes; | ||||
|     private copyBytes; | ||||
| } | ||||
| //# sourceMappingURL=ByteBuffer.d.ts.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"ByteBuffer.d.ts","sourceRoot":"","sources":["../../src/lib/ByteBuffer.ts"],"names":[],"mappings":";AAAA,qBAAa,UAAU;IACtB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,IAAI,CAAS;IAErB;;;OAGG;gBACgB,IAAI,SAAO;IAI9B;;OAEG;IACH,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED;;;OAGG;IACI,KAAK,IAAI,IAAI;IAIpB;;;OAGG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKpC;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAQpD;;;OAGG;IACI,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,SAAI,EAAE,GAAG,SAAe,GAAG,IAAI;IAQhF;;;OAGG;IACI,OAAO,IAAI,MAAM;IAIxB;;;;;OAKG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAI7D,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,SAAS;CASjB"} | ||||
							
								
								
									
										103
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | |||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.ByteBuffer = void 0; | ||||
| class ByteBuffer { | ||||
|     /** | ||||
|      * Constructs the instance. | ||||
|      * @param size The amount of bytes to reserve, defaults to 8KB. | ||||
|      */ | ||||
|     constructor(size = 8192) { | ||||
|         Object.defineProperty(this, "written", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "data", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         this.data = Buffer.allocUnsafe(size); | ||||
|     } | ||||
|     /** | ||||
|      * Gets the written data. | ||||
|      */ | ||||
|     get length() { | ||||
|         return this.written; | ||||
|     } | ||||
|     /** | ||||
|      * Resets the data. | ||||
|      * @note This does not de-allocate the data, instead, it sets the {@link ByteBuffer.written position} to zero. | ||||
|      */ | ||||
|     reset() { | ||||
|         this.written = 0; | ||||
|     } | ||||
|     /** | ||||
|      * Writes a single byte into the buffer. | ||||
|      * @param byte The byte to write, between `0x00` and `0xFF`. | ||||
|      */ | ||||
|     writeByte(byte) { | ||||
|         this.ensureByte(); | ||||
|         this.data[this.written++] = byte; | ||||
|     } | ||||
|     /** | ||||
|      * Writes the `byte` value `times` times. | ||||
|      * @param byte The byte to write `times` times. | ||||
|      * @param times The amount of times to write the `byte`. | ||||
|      */ | ||||
|     writeTimes(byte, times) { | ||||
|         this.ensureBytes(times); | ||||
|         for (let i = 0; i < times; i++) { | ||||
|             this.data[this.written++] = byte; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Writes `bytes` into the data. | ||||
|      * @param bytes The bytes to write. | ||||
|      */ | ||||
|     writeBytes(bytes, start = 0, end = bytes.length) { | ||||
|         this.ensureBytes(end - start); | ||||
|         for (let i = start; i < end; i++) { | ||||
|             this.data[this.written++] = bytes[i]; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Gets a sub-array of what was written so far. | ||||
|      * @returns The written section of the data. | ||||
|      */ | ||||
|     toArray() { | ||||
|         return this.data.subarray(0, this.written); | ||||
|     } | ||||
|     /** | ||||
|      * Fills the data with the `byte` value given a range. | ||||
|      * @param byte The value to write. | ||||
|      * @param start The start index, defaults to `0`. | ||||
|      * @param end The end index, defaults to {@link Uint8Array.length `this.data.length`}. | ||||
|      */ | ||||
|     fill(byte, start, end) { | ||||
|         this.data.fill(byte, start, end); | ||||
|     } | ||||
|     ensureByte() { | ||||
|         if (this.written + 1 >= this.data.length) { | ||||
|             const size = this.data.length * 2; | ||||
|             this.data = this.copyBytes(size); | ||||
|         } | ||||
|     } | ||||
|     ensureBytes(n) { | ||||
|         if (this.written + n >= this.data.length) { | ||||
|             const size = Math.pow(2, Math.ceil(Math.log(this.written + n) / Math.log(2))); | ||||
|             this.data = this.copyBytes(size); | ||||
|         } | ||||
|     } | ||||
|     copyBytes(size) { | ||||
|         const data = Buffer.allocUnsafe(size); | ||||
|         for (let i = 0; i < this.written; ++i) { | ||||
|             data[i] = this.data[i]; | ||||
|         } | ||||
|         return data; | ||||
|     } | ||||
| } | ||||
| exports.ByteBuffer = ByteBuffer; | ||||
| //# sourceMappingURL=ByteBuffer.js.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/ByteBuffer.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"ByteBuffer.js","sourceRoot":"","sources":["../../src/lib/ByteBuffer.ts"],"names":[],"mappings":";;;AAAA,MAAa,UAAU;IAItB;;;OAGG;IACH,YAAmB,IAAI,GAAG,IAAI;QAP9B;;;;mBAAkB,CAAC;WAAC;QACpB;;;;;WAAqB;QAOpB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;;OAGG;IACI,KAAK;QACX,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IAClB,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,IAAY;QAC5B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACI,UAAU,CAAC,IAAY,EAAE,KAAa;QAC5C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;SACjC;IACF,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,KAAwB,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM;QACxE,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QAE9B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;YACjC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;SACrC;IACF,CAAC;IAED;;;OAGG;IACI,OAAO;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACI,IAAI,CAAC,IAAY,EAAE,KAAc,EAAE,GAAY;QACrD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;IAEO,UAAU;QACjB,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SACjC;IACF,CAAC;IAEO,WAAW,CAAC,CAAS;QAC5B,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SACjC;IACF,CAAC;IAEO,SAAS,CAAC,IAAY;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;YACtC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACvB;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AAtGD,gCAsGC"} | ||||
							
								
								
									
										279
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,279 @@ | |||
| /** | ||||
|  * GifEncoder | ||||
|  * | ||||
|  * Authors | ||||
|  * - Kevin Weiner (original Java version - kweiner@fmsware.com) | ||||
|  * - Thibault Imbert (AS3 version - bytearray.org) | ||||
|  * - Johan Nordberg (JS version - code@johan-nordberg.com) | ||||
|  * - Eugene Ware (node.js streaming version - eugene@noblesmaurai.com) | ||||
|  * - Antonio Román (TS version - kyradiscord@gmail.com) | ||||
|  */ | ||||
| /// <reference types="node" />
 | ||||
| import { Duplex, Readable } from 'stream'; | ||||
| /** | ||||
|  * The disposal method code. | ||||
|  * | ||||
|  * - `0`: No disposal specified. The decoder is not required to take any action. | ||||
|  * - `1`: Do not dispose. The graphic is to be left in place. | ||||
|  * - `2`: Restore to background color. The area used by the graphic must be restored to the background color. | ||||
|  * - `3`: Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was | ||||
|  * there prior to rendering the graphic. | ||||
|  * - `4` - `7`: To be defined. | ||||
|  */ | ||||
| export declare type DisposalCode = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; | ||||
| export interface EncoderOptions { | ||||
|     /** | ||||
|      * The frame delay in milliseconds. | ||||
|      * @default 0 | ||||
|      */ | ||||
|     delay?: number; | ||||
|     /** | ||||
|      * The frames per second, supersedes {@link EncoderOptions.delay} if set. | ||||
|      * @default 0 | ||||
|      */ | ||||
|     framerate?: number; | ||||
|     /** | ||||
|      * The GIF frame disposal code for the last added frame and any subsequent frames. | ||||
|      * | ||||
|      * Defaults to one of the following values: | ||||
|      * - `0` : If `transparent` is set | ||||
|      * - `2` : Otherwise | ||||
|      */ | ||||
|     dispose?: DisposalCode; | ||||
|     /** | ||||
|      * The number of times to repeat the GIF, between `0` and `65536`, with two special cases: | ||||
|      * - `-1`: play once | ||||
|      * - `0`: repeat indefinitely | ||||
|      * @default -1 | ||||
|      * @note When set to a value different to `-1`, the GIF will use the Netscape 2.0 extension. | ||||
|      */ | ||||
|     repeat?: number; | ||||
|     /** | ||||
|      * The transparent color for the last added frame and any subsequent frames. Since all colors are subject to | ||||
|      * modification in the quantization process, the color in the final palette for each frame closest to the given | ||||
|      * color becomes the transparent color for that frame. May be set to null to indicate no transparent color. | ||||
|      */ | ||||
|     transparent?: number | null; | ||||
|     /** | ||||
|      * The quality of color quantization (conversion of images to the maximum 256 colors allowed by the GIF | ||||
|      * specification) between `1` and `30`. Lower values (closer to 1) produce better colors but require significantly | ||||
|      * more resources and processing. `10` is the default value as it produces good color mapping at reasonable speeds. | ||||
|      * | ||||
|      * @note Values greater than 20 do not yield significant improvements in speed. | ||||
|      */ | ||||
|     quality?: number; | ||||
| } | ||||
| export declare class GifEncoder { | ||||
|     /** | ||||
|      * The GIF image's width, between `1` and `65536`. | ||||
|      */ | ||||
|     readonly width: number; | ||||
|     /** | ||||
|      * The GIF image's height, between `1` and `65536`. | ||||
|      */ | ||||
|     readonly height: number; | ||||
|     /** | ||||
|      * The transparent color, `null` if no transparent color is given. | ||||
|      */ | ||||
|     private transparent; | ||||
|     /** | ||||
|      * The transparent index in the color table. | ||||
|      */ | ||||
|     private transparentIndex; | ||||
|     /** | ||||
|      * Number between `-1` and `65536`, `-1` indicating no repeat (GIF89a specification), otherwise repeating `repeat` | ||||
|      * times with the exception of `0`, which repeats indefinitely. | ||||
|      */ | ||||
|     private repeat; | ||||
|     /** | ||||
|      * Frame delay in hundredths of a second (1 = 10ms). | ||||
|      */ | ||||
|     private delay; | ||||
|     /** | ||||
|      * The current frame. | ||||
|      */ | ||||
|     private image; | ||||
|     /** | ||||
|      * The BGR byte array from the current frame. | ||||
|      */ | ||||
|     private pixels; | ||||
|     /** | ||||
|      * The converted frame indexed to the palette. | ||||
|      */ | ||||
|     private indexedPixels; | ||||
|     /** | ||||
|      * The number of bit planes. | ||||
|      */ | ||||
|     private colorDepth; | ||||
|     /** | ||||
|      * The RGB palette. | ||||
|      */ | ||||
|     private colorPalette; | ||||
|     /** | ||||
|      * The active palette entries. | ||||
|      */ | ||||
|     private usedEntry; | ||||
|     /** | ||||
|      * The disposal code (`-1` = determine defaults). | ||||
|      */ | ||||
|     private disposalMode; | ||||
|     /** | ||||
|      * Whether or not this is the first frame. | ||||
|      */ | ||||
|     private firstFrame; | ||||
|     /** | ||||
|      * The sample interval for the quantifier. | ||||
|      */ | ||||
|     private sample; | ||||
|     /** | ||||
|      * Whether or not we started encoding. | ||||
|      */ | ||||
|     private started; | ||||
|     /** | ||||
|      * The readable streams. | ||||
|      */ | ||||
|     private readableStreams; | ||||
|     /** | ||||
|      * The output buffer. | ||||
|      */ | ||||
|     private byteBuffer; | ||||
|     /** | ||||
|      * Constructs the GIF encoder. | ||||
|      * @param width An integer representing the GIF image's width, between `1` and `65536`. | ||||
|      * @param height An integer representing the GIF image's height, between `1` and `65536`. | ||||
|      */ | ||||
|     constructor(width: number, height: number); | ||||
|     /** | ||||
|      * Creates a readable stream and pushes it to the encoder's {@link GifEncoder.readableStreams readable streams}. | ||||
|      * @returns The new readable stream. | ||||
|      * @example | ||||
|      * ```javascript
 | ||||
|      * const encoder = new GifEncoder(320, 240); | ||||
|      * | ||||
|      * // Stream the results as they are available into hello.gif
 | ||||
|      * encoder.createReadStream().pipe(fs.createWriteStream('hello.gif')); | ||||
|      * ``` | ||||
|      */ | ||||
|     createReadStream(): Readable; | ||||
|     /** | ||||
|      * Uses an existing readable stream and pushes it to the encoder's {@link GifEncoder.readableStreams readable streams}. | ||||
|      * @param readable The readable stream to use. | ||||
|      * @returns The given readable stream. | ||||
|      */ | ||||
|     createReadStream<T extends Readable>(readable: T): T; | ||||
|     /** | ||||
|      * Creates a write stream. | ||||
|      * @param options The options for the write stream. | ||||
|      * @returns A {@link Duplex}. | ||||
|      * @example | ||||
|      * ```typescript
 | ||||
|      * const { GifEncoder } = require('@skyra/gifenc'); | ||||
|      * const encoder = new GifEncoder(400, 200); | ||||
|      * | ||||
|      * pngStreamGenerator() // A user-defined `Readable`.
 | ||||
|      * 	.pipe(encoder.createWriteStream({ repeat: -1, delay: 500, quality: 10 })) | ||||
|      * 	.pipe(fs.createWriteStream('runningKitten.gif')); | ||||
|      * ``` | ||||
|      */ | ||||
|     createWriteStream(options?: EncoderOptions): Duplex; | ||||
|     /** | ||||
|      * Sets the delay time between each frame, or changes it for subsequent frames (applies to the next frame added). | ||||
|      * @param delay The delay between frames, in milliseconds. Must be a number between `655360` and `10`. | ||||
|      */ | ||||
|     setDelay(delay: number): this; | ||||
|     /** | ||||
|      * Sets frame rate in frames per second. | ||||
|      * @param fps The amount of frames per second, maximum is `100` frames per second. | ||||
|      */ | ||||
|     setFramerate(fps: number): this; | ||||
|     /** | ||||
|      * Sets the GIF frame disposal code for the last added frame and any subsequent frames. | ||||
|      * | ||||
|      * Defaults to one of the following values: | ||||
|      * - `0` : If `transparent` is set | ||||
|      * - `2` : Otherwise | ||||
|      * | ||||
|      * @param disposalCode The disposal code. | ||||
|      * @see {@link DisposalCode} | ||||
|      */ | ||||
|     setDispose(disposalCode: DisposalCode): this; | ||||
|     /** | ||||
|      * Sets the number of times the set of GIF frames should be played. | ||||
|      * @param repeat The number of times between `-1` and `65536` to repeat the GIF, with two special cases: | ||||
|      * - `-1` (**default**): play once | ||||
|      * - `0`: repeat indefinitely | ||||
|      * | ||||
|      * @note This method has no effect after the first image was added. | ||||
|      */ | ||||
|     setRepeat(repeat: number): this; | ||||
|     /** | ||||
|      * Sets the transparent color for the last added frame and any subsequent frames. Since all colors are subject to | ||||
|      * modification in the quantization process, the color in the final palette for each frame closest to the given | ||||
|      * color becomes the transparent color for that frame. May be set to null to indicate no transparent color. | ||||
|      * @param color The color to be set in transparent pixels. | ||||
|      */ | ||||
|     setTransparent(color: number | null): this; | ||||
|     /** | ||||
|      * Sets the quality of color quantization (conversion of images to the maximum 256 colors allowed by the GIF | ||||
|      * specification). Lower values (`minimum` = 1) produce better colors, but slow processing significantly. `10` is | ||||
|      * the default, and produces good color mapping at reasonable speeds. Values greater than 20 do not yield | ||||
|      * significant improvements in speed. | ||||
|      * @param quality A number between `1` and `30`. | ||||
|      */ | ||||
|     setQuality(quality: number): this; | ||||
|     /** | ||||
|      * Adds the next GIF frame. The frame is not written immediately, but is actually deferred until the next frame is | ||||
|      * received so that timing data can be inserted. Calling {@link GifEncoder.finish} will flush all frames. | ||||
|      * @param imageData The image data to add into the next frame. | ||||
|      */ | ||||
|     addFrame(imageData: Pick<CanvasRenderingContext2D, 'getImageData'> | Uint8ClampedArray): void; | ||||
|     /** | ||||
|      * Adds final trailer to the GIF stream, if you don't call the finish method the GIF stream will not be valid. | ||||
|      */ | ||||
|     finish(): void; | ||||
|     /** | ||||
|      * Writes the GIF file header | ||||
|      */ | ||||
|     start(): void; | ||||
|     private end; | ||||
|     private emit; | ||||
|     /** | ||||
|      * Analyzes current frame colors and creates a color map. | ||||
|      */ | ||||
|     private analyzePixels; | ||||
|     /** | ||||
|      * Returns index of palette color closest to c. | ||||
|      * @param color The color to compare. | ||||
|      */ | ||||
|     private findClosest; | ||||
|     /** | ||||
|      * Updates {@link GifEncoder.pixels} by creating an RGB-formatted {@link Uint8Array} from the RGBA-formatted data. | ||||
|      */ | ||||
|     private getImagePixels; | ||||
|     /** | ||||
|      * Writes the GCE (Graphic Control Extension). | ||||
|      */ | ||||
|     private writeGraphicControlExtension; | ||||
|     /** | ||||
|      * Writes the ID (Image Descriptor). | ||||
|      */ | ||||
|     private writeImageDescriptor; | ||||
|     /** | ||||
|      * Writes the LSD (Logical Screen Descriptor) | ||||
|      */ | ||||
|     private writeLogicalScreenDescriptor; | ||||
|     /** | ||||
|      * Writes the Netscape application extension to define repeat count. | ||||
|      */ | ||||
|     private writeNetscapeExtension; | ||||
|     /** | ||||
|      * Writes the color table palette. | ||||
|      */ | ||||
|     private writePalette; | ||||
|     private writeShort; | ||||
|     /** | ||||
|      * Encodes and writes pixel data into {@link GifEncoder.byteBuffer}. | ||||
|      */ | ||||
|     private writePixels; | ||||
| } | ||||
| //# sourceMappingURL=GifEncoder.d.ts.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"GifEncoder.d.ts","sourceRoot":"","sources":["../../src/lib/GifEncoder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAkB1C;;;;;;;;;GASG;AACH,oBAAY,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,UAAU;IACtB;;OAEG;IACH,SAAgB,KAAK,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,WAAW,CAAuB;IAE1C;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAM;IAEpB;;OAEG;IACH,OAAO,CAAC,KAAK,CAAK;IAElB;;OAEG;IACH,OAAO,CAAC,KAAK,CAAkC;IAE/C;;OAEG;IACH,OAAO,CAAC,MAAM,CAA2B;IAEzC;;OAEG;IACH,OAAO,CAAC,aAAa,CAA2B;IAEhD;;OAEG;IACH,OAAO,CAAC,UAAU,CAAuB;IAEzC;;OAEG;IACH,OAAO,CAAC,YAAY,CAA6B;IAEjD;;OAEG;IACH,OAAO,CAAC,SAAS,CAAiB;IAElC;;OAEG;IACH,OAAO,CAAC,YAAY,CAAyB;IAE7C;;OAEG;IACH,OAAO,CAAC,UAAU,CAAQ;IAE1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAM;IAEpB;;OAEG;IACH,OAAO,CAAC,OAAO,CAAS;IAExB;;OAEG;IACH,OAAO,CAAC,eAAe,CAAkB;IAEzC;;OAEG;IACH,OAAO,CAAC,UAAU,CAAoB;IAEtC;;;;OAIG;gBACgB,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKhD;;;;;;;;;;OAUG;IACI,gBAAgB,IAAI,QAAQ;IACnC;;;;OAIG;IACI,gBAAgB,CAAC,CAAC,SAAS,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAW3D;;;;;;;;;;;;;OAaG;IACI,iBAAiB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM;IA8B1D;;;OAGG;IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKpC;;;OAGG;IACI,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKtC;;;;;;;;;OASG;IACI,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAKnD;;;;;;;OAOG;IACI,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKtC;;;;;OAKG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKjD;;;;;;OAMG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMxC;;;;OAIG;IACI,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,wBAAwB,EAAE,cAAc,CAAC,GAAG,iBAAiB;IA4B7F;;OAEG;IACI,MAAM;IAKb;;OAEG;IACI,KAAK;IAMZ,OAAO,CAAC,GAAG;IAWX,OAAO,CAAC,IAAI;IAWZ;;OAEG;IACH,OAAO,CAAC,aAAa;IAsCrB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAmCpC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAmBpC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAa9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,WAAW;CAInB"} | ||||
							
								
								
									
										562
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										562
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,562 @@ | |||
| "use strict"; | ||||
| /** | ||||
|  * GifEncoder | ||||
|  * | ||||
|  * Authors | ||||
|  * - Kevin Weiner (original Java version - kweiner@fmsware.com) | ||||
|  * - Thibault Imbert (AS3 version - bytearray.org) | ||||
|  * - Johan Nordberg (JS version - code@johan-nordberg.com) | ||||
|  * - Eugene Ware (node.js streaming version - eugene@noblesmaurai.com) | ||||
|  * - Antonio Román (TS version - kyradiscord@gmail.com) | ||||
|  */ | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.GifEncoder = void 0; | ||||
| const stream_1 = require("stream"); | ||||
| const util_1 = require("util"); | ||||
| const ByteBuffer_1 = require("./ByteBuffer"); | ||||
| const LZWEncoder_1 = require("./LZWEncoder"); | ||||
| const NeuQuant_1 = require("./NeuQuant"); | ||||
| const NOP = () => { | ||||
|     // no-op
 | ||||
| }; | ||||
| const GIF_HEADER = new TextEncoder().encode('GIF89a'); | ||||
| const NETSCAPE_HEADER = new Uint8Array([0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30]); // NETSCAPE2.0
 | ||||
| /** | ||||
|  * The color table size (bits - 1). | ||||
|  */ | ||||
| const PALETTE_SIZE = 7; | ||||
| class GifEncoder { | ||||
|     /** | ||||
|      * Constructs the GIF encoder. | ||||
|      * @param width An integer representing the GIF image's width, between `1` and `65536`. | ||||
|      * @param height An integer representing the GIF image's height, between `1` and `65536`. | ||||
|      */ | ||||
|     constructor(width, height) { | ||||
|         /** | ||||
|          * The GIF image's width, between `1` and `65536`. | ||||
|          */ | ||||
|         Object.defineProperty(this, "width", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         /** | ||||
|          * The GIF image's height, between `1` and `65536`. | ||||
|          */ | ||||
|         Object.defineProperty(this, "height", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         /** | ||||
|          * The transparent color, `null` if no transparent color is given. | ||||
|          */ | ||||
|         Object.defineProperty(this, "transparent", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: null | ||||
|         }); | ||||
|         /** | ||||
|          * The transparent index in the color table. | ||||
|          */ | ||||
|         Object.defineProperty(this, "transparentIndex", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         /** | ||||
|          * Number between `-1` and `65536`, `-1` indicating no repeat (GIF89a specification), otherwise repeating `repeat` | ||||
|          * times with the exception of `0`, which repeats indefinitely. | ||||
|          */ | ||||
|         Object.defineProperty(this, "repeat", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: -1 | ||||
|         }); | ||||
|         /** | ||||
|          * Frame delay in hundredths of a second (1 = 10ms). | ||||
|          */ | ||||
|         Object.defineProperty(this, "delay", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         /** | ||||
|          * The current frame. | ||||
|          */ | ||||
|         Object.defineProperty(this, "image", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: null | ||||
|         }); | ||||
|         /** | ||||
|          * The BGR byte array from the current frame. | ||||
|          */ | ||||
|         Object.defineProperty(this, "pixels", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: null | ||||
|         }); | ||||
|         /** | ||||
|          * The converted frame indexed to the palette. | ||||
|          */ | ||||
|         Object.defineProperty(this, "indexedPixels", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: null | ||||
|         }); | ||||
|         /** | ||||
|          * The number of bit planes. | ||||
|          */ | ||||
|         Object.defineProperty(this, "colorDepth", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: null | ||||
|         }); | ||||
|         /** | ||||
|          * The RGB palette. | ||||
|          */ | ||||
|         Object.defineProperty(this, "colorPalette", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: null | ||||
|         }); | ||||
|         /** | ||||
|          * The active palette entries. | ||||
|          */ | ||||
|         Object.defineProperty(this, "usedEntry", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: [] | ||||
|         }); | ||||
|         /** | ||||
|          * The disposal code (`-1` = determine defaults). | ||||
|          */ | ||||
|         Object.defineProperty(this, "disposalMode", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: -1 | ||||
|         }); | ||||
|         /** | ||||
|          * Whether or not this is the first frame. | ||||
|          */ | ||||
|         Object.defineProperty(this, "firstFrame", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: true | ||||
|         }); | ||||
|         /** | ||||
|          * The sample interval for the quantifier. | ||||
|          */ | ||||
|         Object.defineProperty(this, "sample", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 10 | ||||
|         }); | ||||
|         /** | ||||
|          * Whether or not we started encoding. | ||||
|          */ | ||||
|         Object.defineProperty(this, "started", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: false | ||||
|         }); | ||||
|         /** | ||||
|          * The readable streams. | ||||
|          */ | ||||
|         Object.defineProperty(this, "readableStreams", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: [] | ||||
|         }); | ||||
|         /** | ||||
|          * The output buffer. | ||||
|          */ | ||||
|         Object.defineProperty(this, "byteBuffer", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: new ByteBuffer_1.ByteBuffer() | ||||
|         }); | ||||
|         this.width = ~~width; | ||||
|         this.height = ~~height; | ||||
|     } | ||||
|     createReadStream(readable) { | ||||
|         if (!readable) { | ||||
|             readable = new stream_1.Readable(); | ||||
|             readable._read = NOP; | ||||
|         } | ||||
|         this.readableStreams.push(readable); | ||||
|         return readable; | ||||
|     } | ||||
|     /** | ||||
|      * Creates a write stream. | ||||
|      * @param options The options for the write stream. | ||||
|      * @returns A {@link Duplex}. | ||||
|      * @example | ||||
|      * ```typescript
 | ||||
|      * const { GifEncoder } = require('@skyra/gifenc'); | ||||
|      * const encoder = new GifEncoder(400, 200); | ||||
|      * | ||||
|      * pngStreamGenerator() // A user-defined `Readable`.
 | ||||
|      * 	.pipe(encoder.createWriteStream({ repeat: -1, delay: 500, quality: 10 })) | ||||
|      * 	.pipe(fs.createWriteStream('runningKitten.gif')); | ||||
|      * ``` | ||||
|      */ | ||||
|     createWriteStream(options) { | ||||
|         if (options) { | ||||
|             if (options.delay !== undefined) | ||||
|                 this.setDelay(options.delay); | ||||
|             if (options.framerate !== undefined) | ||||
|                 this.setFramerate(options.framerate); | ||||
|             if (options.dispose !== undefined) | ||||
|                 this.setDispose(options.dispose); | ||||
|             if (options.repeat !== undefined) | ||||
|                 this.setRepeat(options.repeat); | ||||
|             if (options.transparent !== undefined) | ||||
|                 this.setTransparent(options.transparent); | ||||
|             if (options.quality !== undefined) | ||||
|                 this.setQuality(options.quality); | ||||
|         } | ||||
|         const duplex = new stream_1.Duplex({ objectMode: true }); | ||||
|         duplex._read = NOP; | ||||
|         this.createReadStream(duplex); | ||||
|         duplex._write = (data, _enc, next) => { | ||||
|             if (!this.started) | ||||
|                 this.start(); | ||||
|             this.addFrame(data); | ||||
|             next(); | ||||
|         }; | ||||
|         const end = duplex.end.bind(duplex); | ||||
|         // @ts-expect-error This is a Node 17 issue and it should not break using the library
 | ||||
|         duplex.end = (...args) => { | ||||
|             end(...args); | ||||
|             this.finish(); | ||||
|         }; | ||||
|         return duplex; | ||||
|     } | ||||
|     /** | ||||
|      * Sets the delay time between each frame, or changes it for subsequent frames (applies to the next frame added). | ||||
|      * @param delay The delay between frames, in milliseconds. Must be a number between `655360` and `10`. | ||||
|      */ | ||||
|     setDelay(delay) { | ||||
|         this.delay = Math.round(delay / 10); | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Sets frame rate in frames per second. | ||||
|      * @param fps The amount of frames per second, maximum is `100` frames per second. | ||||
|      */ | ||||
|     setFramerate(fps) { | ||||
|         this.delay = Math.round(100 / fps); | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Sets the GIF frame disposal code for the last added frame and any subsequent frames. | ||||
|      * | ||||
|      * Defaults to one of the following values: | ||||
|      * - `0` : If `transparent` is set | ||||
|      * - `2` : Otherwise | ||||
|      * | ||||
|      * @param disposalCode The disposal code. | ||||
|      * @see {@link DisposalCode} | ||||
|      */ | ||||
|     setDispose(disposalCode) { | ||||
|         if (disposalCode >= 0) | ||||
|             this.disposalMode = disposalCode; | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Sets the number of times the set of GIF frames should be played. | ||||
|      * @param repeat The number of times between `-1` and `65536` to repeat the GIF, with two special cases: | ||||
|      * - `-1` (**default**): play once | ||||
|      * - `0`: repeat indefinitely | ||||
|      * | ||||
|      * @note This method has no effect after the first image was added. | ||||
|      */ | ||||
|     setRepeat(repeat) { | ||||
|         this.repeat = repeat; | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Sets the transparent color for the last added frame and any subsequent frames. Since all colors are subject to | ||||
|      * modification in the quantization process, the color in the final palette for each frame closest to the given | ||||
|      * color becomes the transparent color for that frame. May be set to null to indicate no transparent color. | ||||
|      * @param color The color to be set in transparent pixels. | ||||
|      */ | ||||
|     setTransparent(color) { | ||||
|         this.transparent = color; | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Sets the quality of color quantization (conversion of images to the maximum 256 colors allowed by the GIF | ||||
|      * specification). Lower values (`minimum` = 1) produce better colors, but slow processing significantly. `10` is | ||||
|      * the default, and produces good color mapping at reasonable speeds. Values greater than 20 do not yield | ||||
|      * significant improvements in speed. | ||||
|      * @param quality A number between `1` and `30`. | ||||
|      */ | ||||
|     setQuality(quality) { | ||||
|         if (quality < 1) | ||||
|             quality = 1; | ||||
|         this.sample = quality; | ||||
|         return this; | ||||
|     } | ||||
|     /** | ||||
|      * Adds the next GIF frame. The frame is not written immediately, but is actually deferred until the next frame is | ||||
|      * received so that timing data can be inserted. Calling {@link GifEncoder.finish} will flush all frames. | ||||
|      * @param imageData The image data to add into the next frame. | ||||
|      */ | ||||
|     addFrame(imageData) { | ||||
|         if (util_1.types.isUint8ClampedArray(imageData)) { | ||||
|             this.image = imageData; | ||||
|         } | ||||
|         else { | ||||
|             this.image = imageData.getImageData(0, 0, this.width, this.height).data; | ||||
|         } | ||||
|         this.getImagePixels(); // convert to correct format if necessary
 | ||||
|         this.analyzePixels(); // build color table & map pixels
 | ||||
|         if (this.firstFrame) { | ||||
|             this.writeLogicalScreenDescriptor(); // logical screen descriptor
 | ||||
|             this.writePalette(); // global color table
 | ||||
|             if (this.repeat >= 0) { | ||||
|                 // use NS app extension to indicate reps
 | ||||
|                 this.writeNetscapeExtension(); | ||||
|             } | ||||
|         } | ||||
|         this.writeGraphicControlExtension(); // write graphic control extension
 | ||||
|         this.writeImageDescriptor(); // image descriptor
 | ||||
|         if (!this.firstFrame) | ||||
|             this.writePalette(); // local color table
 | ||||
|         this.writePixels(); // encode and write pixel data
 | ||||
|         this.firstFrame = false; | ||||
|         this.emit(); | ||||
|     } | ||||
|     /** | ||||
|      * Adds final trailer to the GIF stream, if you don't call the finish method the GIF stream will not be valid. | ||||
|      */ | ||||
|     finish() { | ||||
|         this.byteBuffer.writeByte(0x3b); // gif trailer
 | ||||
|         this.end(); | ||||
|     } | ||||
|     /** | ||||
|      * Writes the GIF file header | ||||
|      */ | ||||
|     start() { | ||||
|         this.byteBuffer.writeBytes(GIF_HEADER); | ||||
|         this.started = true; | ||||
|         this.emit(); | ||||
|     } | ||||
|     end() { | ||||
|         if (this.readableStreams.length === 0) | ||||
|             return; | ||||
|         this.emit(); | ||||
|         for (const stream of this.readableStreams) { | ||||
|             stream.push(null); | ||||
|         } | ||||
|         this.readableStreams = []; | ||||
|     } | ||||
|     emit() { | ||||
|         if (this.readableStreams.length === 0 || this.byteBuffer.length === 0) | ||||
|             return; | ||||
|         const data = this.byteBuffer.toArray(); | ||||
|         for (const stream of this.readableStreams) { | ||||
|             stream.push(Buffer.from(data)); | ||||
|         } | ||||
|         this.byteBuffer.reset(); | ||||
|     } | ||||
|     /** | ||||
|      * Analyzes current frame colors and creates a color map. | ||||
|      */ | ||||
|     analyzePixels() { | ||||
|         const pixels = this.pixels; | ||||
|         const pixelByteCount = pixels.length; | ||||
|         const pixelCount = pixelByteCount / 3; | ||||
|         this.indexedPixels = new Uint8Array(pixelCount); | ||||
|         const quantifier = new NeuQuant_1.NeuQuant(pixels, this.sample); | ||||
|         this.colorPalette = quantifier.getColorMap(); | ||||
|         // Map image pixels to new palette:
 | ||||
|         let k = 0; | ||||
|         for (let j = 0; j < pixelCount; j++) { | ||||
|             const r = pixels[k++] & 0xff; | ||||
|             const g = pixels[k++] & 0xff; | ||||
|             const b = pixels[k++] & 0xff; | ||||
|             const index = quantifier.lookupRGB(r, g, b); | ||||
|             this.usedEntry[index] = true; | ||||
|             this.indexedPixels[j] = index; | ||||
|         } | ||||
|         this.pixels = null; | ||||
|         this.colorDepth = 8; | ||||
|         // Get closest match to transparent color if specified:
 | ||||
|         if (this.transparent === null) | ||||
|             return; | ||||
|         this.transparentIndex = this.findClosest(this.transparent); | ||||
|         // Ensure that pixels with full transparency in the RGBA image are using
 | ||||
|         // the selected transparent color index in the indexed image.
 | ||||
|         for (let pixelIndex = 0; pixelIndex < pixelCount; pixelIndex++) { | ||||
|             if (this.image[pixelIndex * 4 + 3] === 0) { | ||||
|                 this.indexedPixels[pixelIndex] = this.transparentIndex; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Returns index of palette color closest to c. | ||||
|      * @param color The color to compare. | ||||
|      */ | ||||
|     findClosest(color) { | ||||
|         if (this.colorPalette === null) | ||||
|             return -1; | ||||
|         const r = (color & 0xff0000) >> 16; | ||||
|         const g = (color & 0x00ff00) >> 8; | ||||
|         const b = color & 0x0000ff; | ||||
|         let minimumIndex = 0; | ||||
|         let distanceMinimum = 256 * 256 * 256; | ||||
|         const len = this.colorPalette.length; | ||||
|         for (let i = 0; i < len;) { | ||||
|             const index = i / 3; | ||||
|             const dr = r - (this.colorPalette[i++] & 0xff); | ||||
|             const dg = g - (this.colorPalette[i++] & 0xff); | ||||
|             const db = b - (this.colorPalette[i++] & 0xff); | ||||
|             const d = dr * dr + dg * dg + db * db; | ||||
|             if (this.usedEntry[index] && d < distanceMinimum) { | ||||
|                 distanceMinimum = d; | ||||
|                 minimumIndex = index; | ||||
|             } | ||||
|         } | ||||
|         return minimumIndex; | ||||
|     } | ||||
|     /** | ||||
|      * Updates {@link GifEncoder.pixels} by creating an RGB-formatted {@link Uint8Array} from the RGBA-formatted data. | ||||
|      */ | ||||
|     getImagePixels() { | ||||
|         const w = this.width; | ||||
|         const h = this.height; | ||||
|         this.pixels = new Uint8Array(w * h * 3); | ||||
|         const data = this.image; | ||||
|         for (let i = 0, count = 0; i < h; i++) { | ||||
|             for (let j = 0; j < w; j++) { | ||||
|                 const b = i * w * 4 + j * 4; | ||||
|                 this.pixels[count++] = data[b]; | ||||
|                 this.pixels[count++] = data[b + 1]; | ||||
|                 this.pixels[count++] = data[b + 2]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Writes the GCE (Graphic Control Extension). | ||||
|      */ | ||||
|     writeGraphicControlExtension() { | ||||
|         this.byteBuffer.writeByte(0x21); // extension introducer
 | ||||
|         this.byteBuffer.writeByte(0xf9); // GCE label
 | ||||
|         this.byteBuffer.writeByte(4); // data block size
 | ||||
|         let transparency; | ||||
|         let dispose; | ||||
|         if (this.transparent === null) { | ||||
|             transparency = 0; | ||||
|             dispose = 0; // dispose = no action
 | ||||
|         } | ||||
|         else { | ||||
|             transparency = 1; | ||||
|             dispose = 2; // force clear if using transparent color
 | ||||
|         } | ||||
|         if (this.disposalMode >= 0) { | ||||
|             dispose = this.disposalMode & 7; // user override
 | ||||
|         } | ||||
|         dispose <<= 2; | ||||
|         // Write GCP's packed fields
 | ||||
|         const fields = 0 | // XXX0_0000 : Reserved
 | ||||
|             dispose | //     000X_XX00 : Disposal Method
 | ||||
|             0 | // 0000_00X0 : User Input Flag
 | ||||
|             transparency; // 0000_000X : Transparent Color Flag
 | ||||
|         this.byteBuffer.writeByte(fields); | ||||
|         this.writeShort(this.delay); // delay x 1 / 100 sec
 | ||||
|         this.byteBuffer.writeByte(this.transparentIndex); // transparent color index
 | ||||
|         this.byteBuffer.writeByte(0); // block terminator
 | ||||
|     } | ||||
|     /** | ||||
|      * Writes the ID (Image Descriptor). | ||||
|      */ | ||||
|     writeImageDescriptor() { | ||||
|         this.byteBuffer.writeByte(0x2c); //     Image Descriptor block identifier
 | ||||
|         this.writeShort(0); //           Image Left Position
 | ||||
|         this.writeShort(0); //           Image Top Position
 | ||||
|         this.writeShort(this.width); //  Image Width
 | ||||
|         this.writeShort(this.height); // Image Height
 | ||||
|         // Write the LCT (Local Color Table):
 | ||||
|         const fields = this.firstFrame | ||||
|             ? 0 // The first frame uses the GCT (Global Color Table)
 | ||||
|             : 128 | //     X000_0000 : Local Color Table Flag = 1
 | ||||
|                 0 | //     0X00_0000 : Interlace Flag = 0
 | ||||
|                 0 | //     00X0_0000 : Sort Flag = 0
 | ||||
|                 0 | //     000X_X000 : Reserved
 | ||||
|                 PALETTE_SIZE; // 0000_0XXX : Size of Local Color Table
 | ||||
|         this.byteBuffer.writeByte(fields); | ||||
|     } | ||||
|     /** | ||||
|      * Writes the LSD (Logical Screen Descriptor) | ||||
|      */ | ||||
|     writeLogicalScreenDescriptor() { | ||||
|         // logical screen size
 | ||||
|         this.writeShort(this.width); | ||||
|         this.writeShort(this.height); | ||||
|         // Write the GCT (Global Color Table):
 | ||||
|         const fields = 128 | // X000_0000     : GCT (Global Color Table) flag = 1
 | ||||
|             112 | // 0XXX_0000     : Color Resolution = 7
 | ||||
|             0 | // 0000_X000     : GCT sort flag = 0
 | ||||
|             0 | // 0000_0X00     : Reserved
 | ||||
|             PALETTE_SIZE; // 0000_00XX : GCT (Global Color Table) size
 | ||||
|         this.byteBuffer.writeByte(fields); | ||||
|         this.byteBuffer.writeByte(0x000000); // background color index
 | ||||
|         this.byteBuffer.writeByte(0); // pixel aspect ratio - assume 1:1
 | ||||
|     } | ||||
|     /** | ||||
|      * Writes the Netscape application extension to define repeat count. | ||||
|      */ | ||||
|     writeNetscapeExtension() { | ||||
|         // Reference: http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
 | ||||
|         this.byteBuffer.writeByte(0x21); //             Extension
 | ||||
|         this.byteBuffer.writeByte(0xff); //             Application Extension
 | ||||
|         this.byteBuffer.writeByte(0x0b); //             Block Size
 | ||||
|         this.byteBuffer.writeBytes(NETSCAPE_HEADER); // Application Identifier + Application Authentication Code
 | ||||
|         this.byteBuffer.writeByte(0x03); //             Sub-block data size
 | ||||
|         this.byteBuffer.writeByte(0x01); //             Sub-block ID
 | ||||
|         this.writeShort(this.repeat); //         Loop Count (up to 2 bytes, `0` = repeat forever)
 | ||||
|         this.byteBuffer.writeByte(0); //                Block Terminator
 | ||||
|     } | ||||
|     /** | ||||
|      * Writes the color table palette. | ||||
|      */ | ||||
|     writePalette() { | ||||
|         this.byteBuffer.writeBytes(this.colorPalette); | ||||
|         this.byteBuffer.writeTimes(0, 3 * 256 - this.colorPalette.length); | ||||
|     } | ||||
|     writeShort(pValue) { | ||||
|         this.byteBuffer.writeByte(pValue & 0xff); | ||||
|         this.byteBuffer.writeByte((pValue >> 8) & 0xff); | ||||
|     } | ||||
|     /** | ||||
|      * Encodes and writes pixel data into {@link GifEncoder.byteBuffer}. | ||||
|      */ | ||||
|     writePixels() { | ||||
|         const enc = new LZWEncoder_1.LZWEncoder(this.width, this.height, this.indexedPixels, this.colorDepth); | ||||
|         enc.encode(this.byteBuffer); | ||||
|     } | ||||
| } | ||||
| exports.GifEncoder = GifEncoder; | ||||
| //# sourceMappingURL=GifEncoder.js.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/GifEncoder.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										123
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,123 @@ | |||
| /** | ||||
|  * LZWEncoder | ||||
|  * | ||||
|  * Authors | ||||
|  * - Kevin Weiner (original Java version - kweiner@fmsware.com) | ||||
|  * - Thibault Imbert (AS3 version - bytearray.org) | ||||
|  * - Johan Nordberg (JS version - code@johan-nordberg.com) | ||||
|  * - Antonio Román (TS version - kyradiscord@gmail.com) | ||||
|  * | ||||
|  * Acknowledgements | ||||
|  * - GIFCOMPR.C - GIF Image compression routines | ||||
|  * - Lempel-Ziv compression based on 'compress'. GIF modifications by | ||||
|  * - David Rowley (mgardi@watdcsu.waterloo.edu) | ||||
|  *   GIF Image compression - modified 'compress' | ||||
|  *   Based on: compress.c - File compression ala IEEE Computer, June 1984. | ||||
|  *   By Authors: | ||||
|  *   - Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) | ||||
|  *   - Jim McKie (decvax!mcvax!jim) | ||||
|  *   - Steve Davies (decvax!vax135!petsd!peora!srd) | ||||
|  *   - Ken Turkowski (decvax!decwrl!turtlevax!ken) | ||||
|  *   - James A. Woods (decvax!ihnp4!ames!jaw) | ||||
|  *   - Joe Orost (decvax!vax135!petsd!joe) | ||||
|  */ | ||||
| import type { ByteBuffer } from './ByteBuffer'; | ||||
| /** | ||||
|  * @summary | ||||
|  * Algorithm: use open addressing double hashing (no chaining) on the prefix code / next character combination. | ||||
|  * | ||||
|  * We do a variant of Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime secondary probe. | ||||
|  * Here, the modular division first probe is gives way to a faster exclusive-or manipulation. Also do block compression | ||||
|  * with an adaptive reset, whereby the code table is cleared when the compression ratio decreases, but after the table | ||||
|  * fills. The variable-length output codes are re-sized at this point, and a special CLEAR code is generated for the | ||||
|  * decompression. | ||||
|  * | ||||
|  * **Late addition**: construct the table according to file size for noticeable speed improvement on small files. Please | ||||
|  * direct questions about this implementation to ames!jaw. | ||||
|  */ | ||||
| export declare class LZWEncoder { | ||||
|     /** | ||||
|      * The GIF image's width, between `1` and `65536`. | ||||
|      */ | ||||
|     readonly width: number; | ||||
|     /** | ||||
|      * The GIF image's height, between `1` and `65536`. | ||||
|      */ | ||||
|     readonly height: number; | ||||
|     private pixels; | ||||
|     private readonly initCodeSize; | ||||
|     private currentAccumulator; | ||||
|     private currentBits; | ||||
|     private currentPixel; | ||||
|     private accumulator; | ||||
|     private firstUnusedEntry; | ||||
|     private maximumCode; | ||||
|     private remaining; | ||||
|     private bitSize; | ||||
|     private clearFlag; | ||||
|     private globalInitialBits; | ||||
|     private clearCode; | ||||
|     private endOfFrameCode; | ||||
|     private readonly accumulators; | ||||
|     private readonly hashes; | ||||
|     private readonly codes; | ||||
|     /** | ||||
|      * Constructs a {@link LZWEncoder} instance. | ||||
|      * @param width The width of the image. | ||||
|      * @param height The height of the image. | ||||
|      * @param pixels The pixel data in RGB format. | ||||
|      * @param colorDepth The color depth. | ||||
|      */ | ||||
|     constructor(width: number, height: number, pixels: Uint8Array, colorDepth: number); | ||||
|     /** | ||||
|      * Encodes the image into the output. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     encode(output: ByteBuffer): void; | ||||
|     /** | ||||
|      * Compresses the GIF data. | ||||
|      * @param initialBits The initial bits for the compression. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     private compress; | ||||
|     /** | ||||
|      * Adds a character to the end of the current packet, and if it is at 254 characters, it flushes the packet to disk | ||||
|      * via {@link LZWEncoder.flushPacket}. | ||||
|      * @param c The character code to add. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     private addCharacter; | ||||
|     /** | ||||
|      * Clears out the hash table for block compress. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     private clearCodeTable; | ||||
|     /** | ||||
|      * Resets the hash table given an amount of hashes. | ||||
|      * @param hashSize The amount of hashes to reset. | ||||
|      */ | ||||
|     private resetHashRange; | ||||
|     /** | ||||
|      * Flushes the packet to disk, and reset the accumulator. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     private flushPacket; | ||||
|     /** | ||||
|      * Gets the maximum representable number for a given amount of bits. | ||||
|      * @param size The bit size to get the number from. | ||||
|      * @returns The maximum code given a number of bits. | ||||
|      * @example | ||||
|      * ```typescript
 | ||||
|      * getMaximumCode(6); | ||||
|      * // ➡ 0b0011_1111
 | ||||
|      * ``` | ||||
|      */ | ||||
|     private getMaximumCode; | ||||
|     /** | ||||
|      * Gets the next pixel from the image. | ||||
|      * @returns The next pixel from the image. | ||||
|      */ | ||||
|     private nextPixel; | ||||
|     private processOutput; | ||||
| } | ||||
| //# sourceMappingURL=LZWEncoder.d.ts.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"LZWEncoder.d.ts","sourceRoot":"","sources":["../../src/lib/LZWEncoder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAS/C;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAU;IACtB;;OAEG;IACH,SAAgB,KAAK,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAK;IAIpB,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,cAAc,CAAK;IAE3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD;;;;;;OAMG;gBACgB,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM;IAOxF;;;OAGG;IACI,MAAM,CAAC,MAAM,EAAE,UAAU;IAQhC;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAgEhB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAKpB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAItB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAQnB;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;IAItB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,aAAa;CAmCrB"} | ||||
							
								
								
									
										353
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,353 @@ | |||
| "use strict"; | ||||
| /** | ||||
|  * LZWEncoder | ||||
|  * | ||||
|  * Authors | ||||
|  * - Kevin Weiner (original Java version - kweiner@fmsware.com) | ||||
|  * - Thibault Imbert (AS3 version - bytearray.org) | ||||
|  * - Johan Nordberg (JS version - code@johan-nordberg.com) | ||||
|  * - Antonio Román (TS version - kyradiscord@gmail.com) | ||||
|  * | ||||
|  * Acknowledgements | ||||
|  * - GIFCOMPR.C - GIF Image compression routines | ||||
|  * - Lempel-Ziv compression based on 'compress'. GIF modifications by | ||||
|  * - David Rowley (mgardi@watdcsu.waterloo.edu) | ||||
|  *   GIF Image compression - modified 'compress' | ||||
|  *   Based on: compress.c - File compression ala IEEE Computer, June 1984. | ||||
|  *   By Authors: | ||||
|  *   - Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) | ||||
|  *   - Jim McKie (decvax!mcvax!jim) | ||||
|  *   - Steve Davies (decvax!vax135!petsd!peora!srd) | ||||
|  *   - Ken Turkowski (decvax!decwrl!turtlevax!ken) | ||||
|  *   - James A. Woods (decvax!ihnp4!ames!jaw) | ||||
|  *   - Joe Orost (decvax!vax135!petsd!joe) | ||||
|  */ | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.LZWEncoder = void 0; | ||||
| const EOF = -1; | ||||
| const BITS = 12; | ||||
| const HASH_SIZE = 5003; // 80% occupancy
 | ||||
| const masks = new Uint16Array([ | ||||
|     0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | ||||
| ]); | ||||
| /** | ||||
|  * @summary | ||||
|  * Algorithm: use open addressing double hashing (no chaining) on the prefix code / next character combination. | ||||
|  * | ||||
|  * We do a variant of Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime secondary probe. | ||||
|  * Here, the modular division first probe is gives way to a faster exclusive-or manipulation. Also do block compression | ||||
|  * with an adaptive reset, whereby the code table is cleared when the compression ratio decreases, but after the table | ||||
|  * fills. The variable-length output codes are re-sized at this point, and a special CLEAR code is generated for the | ||||
|  * decompression. | ||||
|  * | ||||
|  * **Late addition**: construct the table according to file size for noticeable speed improvement on small files. Please | ||||
|  * direct questions about this implementation to ames!jaw. | ||||
|  */ | ||||
| class LZWEncoder { | ||||
|     /** | ||||
|      * Constructs a {@link LZWEncoder} instance. | ||||
|      * @param width The width of the image. | ||||
|      * @param height The height of the image. | ||||
|      * @param pixels The pixel data in RGB format. | ||||
|      * @param colorDepth The color depth. | ||||
|      */ | ||||
|     constructor(width, height, pixels, colorDepth) { | ||||
|         /** | ||||
|          * The GIF image's width, between `1` and `65536`. | ||||
|          */ | ||||
|         Object.defineProperty(this, "width", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         /** | ||||
|          * The GIF image's height, between `1` and `65536`. | ||||
|          */ | ||||
|         Object.defineProperty(this, "height", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "pixels", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "initCodeSize", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "currentAccumulator", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "currentBits", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "currentPixel", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "accumulator", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "firstUnusedEntry", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); // first unused entry
 | ||||
|         Object.defineProperty(this, "maximumCode", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "remaining", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "bitSize", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         // block compression parameters -- after all codes are used up,
 | ||||
|         // and compression rate changes, start over.
 | ||||
|         Object.defineProperty(this, "clearFlag", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: false | ||||
|         }); | ||||
|         Object.defineProperty(this, "globalInitialBits", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "clearCode", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "endOfFrameCode", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "accumulators", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: new Uint8Array(256) | ||||
|         }); | ||||
|         Object.defineProperty(this, "hashes", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: new Int32Array(HASH_SIZE) | ||||
|         }); | ||||
|         Object.defineProperty(this, "codes", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: new Int32Array(HASH_SIZE) | ||||
|         }); | ||||
|         this.width = width; | ||||
|         this.height = height; | ||||
|         this.pixels = pixels; | ||||
|         this.initCodeSize = Math.max(2, colorDepth); | ||||
|     } | ||||
|     /** | ||||
|      * Encodes the image into the output. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     encode(output) { | ||||
|         output.writeByte(this.initCodeSize); // write "initial code size" byte
 | ||||
|         this.remaining = this.width * this.height; // reset navigation variables
 | ||||
|         this.currentPixel = 0; | ||||
|         this.compress(this.initCodeSize + 1, output); // compress and write the pixel data
 | ||||
|         output.writeByte(0); // write block terminator
 | ||||
|     } | ||||
|     /** | ||||
|      * Compresses the GIF data. | ||||
|      * @param initialBits The initial bits for the compression. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     compress(initialBits, output) { | ||||
|         // Set up the globals: globalInitialBits - initial number of bits
 | ||||
|         this.globalInitialBits = initialBits; | ||||
|         // Set up the necessary values
 | ||||
|         this.clearFlag = false; | ||||
|         this.bitSize = this.globalInitialBits; | ||||
|         this.maximumCode = this.getMaximumCode(this.bitSize); | ||||
|         this.clearCode = 1 << (initialBits - 1); | ||||
|         this.endOfFrameCode = this.clearCode + 1; | ||||
|         this.firstUnusedEntry = this.clearCode + 2; | ||||
|         // Clear packet
 | ||||
|         this.accumulator = 0; | ||||
|         let code = this.nextPixel(); | ||||
|         let hash = 80048; | ||||
|         const hashShift = 4; | ||||
|         const hashSizeRegion = HASH_SIZE; | ||||
|         this.resetHashRange(hashSizeRegion); | ||||
|         this.processOutput(this.clearCode, output); | ||||
|         let c; | ||||
|         outerLoop: while ((c = this.nextPixel()) !== EOF) { | ||||
|             hash = (c << BITS) + code; | ||||
|             // XOR hashing:
 | ||||
|             let i = (c << hashShift) ^ code; | ||||
|             if (this.hashes[i] === hash) { | ||||
|                 code = this.codes[i]; | ||||
|                 continue; | ||||
|             } | ||||
|             if (this.hashes[i] >= 0) { | ||||
|                 // Non-empty slot, perform secondary hash (after G. Knott):
 | ||||
|                 let dispose = hashSizeRegion - i; | ||||
|                 if (i === 0) | ||||
|                     dispose = 1; | ||||
|                 do { | ||||
|                     if ((i -= dispose) < 0) | ||||
|                         i += hashSizeRegion; | ||||
|                     if (this.hashes[i] === hash) { | ||||
|                         code = this.codes[i]; | ||||
|                         continue outerLoop; | ||||
|                     } | ||||
|                 } while (this.hashes[i] >= 0); | ||||
|             } | ||||
|             this.processOutput(code, output); | ||||
|             code = c; | ||||
|             if (this.firstUnusedEntry < 1 << BITS) { | ||||
|                 // code -> hash-table
 | ||||
|                 this.codes[i] = this.firstUnusedEntry++; | ||||
|                 this.hashes[i] = hash; | ||||
|             } | ||||
|             else { | ||||
|                 this.clearCodeTable(output); | ||||
|             } | ||||
|         } | ||||
|         // Put out the final code:
 | ||||
|         this.processOutput(code, output); | ||||
|         this.processOutput(this.endOfFrameCode, output); | ||||
|     } | ||||
|     /** | ||||
|      * Adds a character to the end of the current packet, and if it is at 254 characters, it flushes the packet to disk | ||||
|      * via {@link LZWEncoder.flushPacket}. | ||||
|      * @param c The character code to add. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     addCharacter(c, output) { | ||||
|         this.accumulators[this.accumulator++] = c; | ||||
|         if (this.accumulator >= 254) | ||||
|             this.flushPacket(output); | ||||
|     } | ||||
|     /** | ||||
|      * Clears out the hash table for block compress. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     clearCodeTable(output) { | ||||
|         this.resetHashRange(HASH_SIZE); | ||||
|         this.firstUnusedEntry = this.clearCode + 2; | ||||
|         this.clearFlag = true; | ||||
|         this.processOutput(this.clearCode, output); | ||||
|     } | ||||
|     /** | ||||
|      * Resets the hash table given an amount of hashes. | ||||
|      * @param hashSize The amount of hashes to reset. | ||||
|      */ | ||||
|     resetHashRange(hashSize) { | ||||
|         this.hashes.fill(-1, 0, hashSize); | ||||
|     } | ||||
|     /** | ||||
|      * Flushes the packet to disk, and reset the accumulator. | ||||
|      * @param output The byte buffer to write to. | ||||
|      */ | ||||
|     flushPacket(output) { | ||||
|         if (this.accumulator > 0) { | ||||
|             output.writeByte(this.accumulator); | ||||
|             output.writeBytes(this.accumulators, 0, this.accumulator); | ||||
|             this.accumulator = 0; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Gets the maximum representable number for a given amount of bits. | ||||
|      * @param size The bit size to get the number from. | ||||
|      * @returns The maximum code given a number of bits. | ||||
|      * @example | ||||
|      * ```typescript
 | ||||
|      * getMaximumCode(6); | ||||
|      * // ➡ 0b0011_1111
 | ||||
|      * ``` | ||||
|      */ | ||||
|     getMaximumCode(size) { | ||||
|         return (1 << size) - 1; | ||||
|     } | ||||
|     /** | ||||
|      * Gets the next pixel from the image. | ||||
|      * @returns The next pixel from the image. | ||||
|      */ | ||||
|     nextPixel() { | ||||
|         if (this.remaining === 0) | ||||
|             return EOF; | ||||
|         --this.remaining; | ||||
|         const pixel = this.pixels[this.currentPixel++]; | ||||
|         return pixel & 0xff; | ||||
|     } | ||||
|     processOutput(code, outs) { | ||||
|         this.currentAccumulator &= masks[this.currentBits]; | ||||
|         this.currentAccumulator = this.currentBits > 0 ? (this.currentAccumulator |= code << this.currentBits) : code; | ||||
|         this.currentBits += this.bitSize; | ||||
|         while (this.currentBits >= 8) { | ||||
|             this.addCharacter(this.currentAccumulator & 0xff, outs); | ||||
|             this.currentAccumulator >>= 8; | ||||
|             this.currentBits -= 8; | ||||
|         } | ||||
|         // If the next entry is going to be too big for the code size,
 | ||||
|         // then increase it, if possible.
 | ||||
|         if (this.firstUnusedEntry > this.maximumCode || this.clearFlag) { | ||||
|             if (this.clearFlag) { | ||||
|                 this.maximumCode = this.getMaximumCode((this.bitSize = this.globalInitialBits)); | ||||
|                 this.clearFlag = false; | ||||
|             } | ||||
|             else { | ||||
|                 ++this.bitSize; | ||||
|                 if (this.bitSize === BITS) | ||||
|                     this.maximumCode = 1 << BITS; | ||||
|                 else | ||||
|                     this.maximumCode = this.getMaximumCode(this.bitSize); | ||||
|             } | ||||
|         } | ||||
|         if (code === this.endOfFrameCode) { | ||||
|             // At EOF, write the rest of the buffer.
 | ||||
|             while (this.currentBits > 0) { | ||||
|                 this.addCharacter(this.currentAccumulator & 0xff, outs); | ||||
|                 this.currentAccumulator >>= 8; | ||||
|                 this.currentBits -= 8; | ||||
|             } | ||||
|             this.flushPacket(outs); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| exports.LZWEncoder = LZWEncoder; | ||||
| //# sourceMappingURL=LZWEncoder.js.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/LZWEncoder.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										121
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.d.ts
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,121 @@ | |||
| /** | ||||
|  * NeuQuant Neural-Net Quantization Algorithm | ||||
|  * ------------------------------------------ | ||||
|  * | ||||
|  * Copyright (c) 1994 Anthony Dekker | ||||
|  * | ||||
|  * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. | ||||
|  * See "Kohonen neural networks for optimal colour quantization" | ||||
|  * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. | ||||
|  * for a discussion of the algorithm. | ||||
|  * See also  http://members.ozemail.com.au/~dekker/NEUQUANT.HTML
 | ||||
|  * | ||||
|  * Any party obtaining a copy of these files from the author, directly or | ||||
|  * indirectly, is granted, free of charge, a full and unrestricted irrevocable, | ||||
|  * world-wide, paid up, royalty-free, nonexclusive right and license to deal | ||||
|  * in this software and documentation files (the "Software"), including without | ||||
|  * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons who receive | ||||
|  * copies from any such party to do so, with the only requirement being | ||||
|  * that this copyright notice remain intact. | ||||
|  * | ||||
|  * (JavaScript port 2012 by Johan Nordberg) | ||||
|  * (TypeScript port 2021 by Antonio Román) | ||||
|  */ | ||||
| export declare class NeuQuant { | ||||
|     /** | ||||
|      * Array of pixels in RGB format, as such that it's decoded as `[r, g, b, r, g, b, r, g, b, ...]`. | ||||
|      */ | ||||
|     private pixels; | ||||
|     /** | ||||
|      * Sampling factor from `1` to `30`, where lower is better quality. | ||||
|      */ | ||||
|     private sampleFactorial; | ||||
|     /** | ||||
|      * The neural networks, composed by {@link maximumColorsSize} {@link Float64Array float arrays} of size 4. | ||||
|      */ | ||||
|     private networks; | ||||
|     /** | ||||
|      * Network lookup indexes, composed by 256 indexes. | ||||
|      */ | ||||
|     private networkIndexes; | ||||
|     private biases; | ||||
|     private frequencies; | ||||
|     private radiusPowers; | ||||
|     /** | ||||
|      * Creates the neural quantifier instance. | ||||
|      * @param pixels Array of pixels in RGB format, as such that it's decoded as `[r, g, b, r, g, b, r, g, b, ...]`. | ||||
|      * @param sampleFactorial Sampling factor from `1` to `30`, where lower is better quality. | ||||
|      */ | ||||
|     constructor(pixels: Uint8Array, sampleFactorial: number); | ||||
|     /** | ||||
|      * Builds the networks' color map. | ||||
|      * @returns A RGB-encoded {@link Float64Array}. | ||||
|      */ | ||||
|     getColorMap(): Float64Array; | ||||
|     /** | ||||
|      * Searches for BGR values 0..255 and returns a color index | ||||
|      * @param b The blue color byte, between 0 and 255. | ||||
|      * @param g The green color byte, between 0 and 255. | ||||
|      * @param r The red color byte, between 0 and 255. | ||||
|      * @returns The best color index. | ||||
|      */ | ||||
|     lookupRGB(b: number, g: number, r: number): number; | ||||
|     /** | ||||
|      * Initializes the state for the arrays. | ||||
|      */ | ||||
|     private init; | ||||
|     /** | ||||
|      * Un-biases network to give byte values 0..255 and record position i to prepare for sort. | ||||
|      */ | ||||
|     private unBiasNetwork; | ||||
|     /** | ||||
|      * Moves neuron `i` towards biased (`B`, `G`, `R`) by factor `alpha`. | ||||
|      * @param alpha The factor at which the neuron `i` should move towards. | ||||
|      * @param i The neuron's index. | ||||
|      * @param b The blue color. | ||||
|      * @param g The green color. | ||||
|      * @param r The red color. | ||||
|      */ | ||||
|     private alterSingle; | ||||
|     /** | ||||
|      * Moves neurons in a `radius` around index `i` towards biased (`B`, `G`, `R`) by factor | ||||
|      * {@link NeuQuant.radiusPowers `radiusPower[m]`}. | ||||
|      * @param radius The radius around `i` to alter. | ||||
|      * @param i The neuron's index. | ||||
|      * @param b The blue color. | ||||
|      * @param g The green color. | ||||
|      * @param r The red color. | ||||
|      */ | ||||
|     private alterNeighbors; | ||||
|     /** | ||||
|      * Searches for biased BGR values. | ||||
|      * | ||||
|      * - Finds the closest neuron (minimum distance) and updates {@link NeuQuant.frequencies}. | ||||
|      * - Finds the best neuron (minimum distance-bias) and returns the position. | ||||
|      * | ||||
|      * For frequently chosen neurons, {@link NeuQuant.frequencies `frequencies[i]`} is high and | ||||
|      * {@link NeuQuant.biases `biases[i]`} is negative. | ||||
|      * | ||||
|      * The latter is determined by the multiplication of `gamma` with the subtraction of the inverse of | ||||
|      * {@link maximumColorsSize} with {@link NeuQuant.frequencies `frequencies[i]`}: | ||||
|      * | ||||
|      * ```typescript
 | ||||
|      * biases[i] = gamma * ((1 / maximumColorsSize) - frequencies[i]) | ||||
|      * ``` | ||||
|      * @param b The blue color. | ||||
|      * @param g The green color. | ||||
|      * @param r The red color. | ||||
|      * @returns The best bias position. | ||||
|      */ | ||||
|     private contest; | ||||
|     /** | ||||
|      * Sorts the neural network and builds {@link NeuQuant.networkIndexes `networkIndex[0..255]`}. | ||||
|      */ | ||||
|     private buildIndexes; | ||||
|     /** | ||||
|      * Runs the main learning loop. | ||||
|      */ | ||||
|     private learn; | ||||
| } | ||||
| //# sourceMappingURL=NeuQuant.d.ts.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.d.ts.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {"version":3,"file":"NeuQuant.d.ts","sourceRoot":"","sources":["../../src/lib/NeuQuant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA2CH,qBAAa,QAAQ;IACpB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAa;IAE3B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAS;IAEhC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAiB;IAEjC;;OAEG;IACH,OAAO,CAAC,cAAc,CAAa;IAGnC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;IAEjC;;;;OAIG;gBACgB,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM;IAe9D;;;OAGG;IACI,WAAW;IAkBlB;;;;;;OAMG;IACI,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAwDhD;;OAEG;IACH,OAAO,CAAC,IAAI;IASZ;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;IAOnB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IA2BtB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,OAAO;IAgCf;;OAEG;IACH,OAAO,CAAC,YAAY;IA4CpB;;OAEG;IACH,OAAO,CAAC,KAAK;CA0Db"} | ||||
							
								
								
									
										427
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,427 @@ | |||
| "use strict"; | ||||
| /** | ||||
|  * NeuQuant Neural-Net Quantization Algorithm | ||||
|  * ------------------------------------------ | ||||
|  * | ||||
|  * Copyright (c) 1994 Anthony Dekker | ||||
|  * | ||||
|  * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. | ||||
|  * See "Kohonen neural networks for optimal colour quantization" | ||||
|  * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. | ||||
|  * for a discussion of the algorithm. | ||||
|  * See also  http://members.ozemail.com.au/~dekker/NEUQUANT.HTML
 | ||||
|  * | ||||
|  * Any party obtaining a copy of these files from the author, directly or | ||||
|  * indirectly, is granted, free of charge, a full and unrestricted irrevocable, | ||||
|  * world-wide, paid up, royalty-free, nonexclusive right and license to deal | ||||
|  * in this software and documentation files (the "Software"), including without | ||||
|  * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons who receive | ||||
|  * copies from any such party to do so, with the only requirement being | ||||
|  * that this copyright notice remain intact. | ||||
|  * | ||||
|  * (JavaScript port 2012 by Johan Nordberg) | ||||
|  * (TypeScript port 2021 by Antonio Román) | ||||
|  */ | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.NeuQuant = void 0; | ||||
| /* eslint-disable prefer-destructuring, no-negated-condition */ | ||||
| const learningCycles = 100; // Number of learning cycles.
 | ||||
| const maximumColorsSize = 256; // Number of colors used.
 | ||||
| const maximumColorsPosition = maximumColorsSize - 1; | ||||
| // defs for freq and bias
 | ||||
| const networkBiasShift = 4; // Bias for color values.
 | ||||
| const integerBiasShift = 16; // Bias for fractions.
 | ||||
| const integerBias = 1 << integerBiasShift; | ||||
| const gammaShift = 10; | ||||
| const betaShift = 10; | ||||
| const beta = integerBias >> betaShift; // `beta` = 1 / 1024
 | ||||
| const betaGamma = integerBias << (gammaShift - betaShift); | ||||
| // Defaults for decreasing radius factor:
 | ||||
| // -> For 256 colors, radius starts at 32.0 biased by 6 bits and decreases by a factor of 1 / 30 each cycle.
 | ||||
| const maximumRadius = maximumColorsSize >> 3; | ||||
| const initialRadiusBiasShift = 6; | ||||
| const initialRadiusBias = 1 << initialRadiusBiasShift; | ||||
| const initialRadius = maximumRadius * initialRadiusBias; | ||||
| const initialRadiusDecrement = 30; | ||||
| // Defaults for decreasing alpha factor:
 | ||||
| // -> Alpha starts at 1.0
 | ||||
| const alphaBiasShift = 10; | ||||
| const initialAlpha = 1 << alphaBiasShift; | ||||
| // Constants used for radius power calculation:
 | ||||
| const radiusBiasShift = 8; | ||||
| const radiusBias = 1 << radiusBiasShift; | ||||
| const alphaRadiusBiasShift = alphaBiasShift + radiusBiasShift; | ||||
| const alphaRadiusBias = 1 << alphaRadiusBiasShift; | ||||
| // Four primes near 500 - assume no image has a length so large that it is divisible by all four primes:
 | ||||
| const prime1 = 499; | ||||
| const prime2 = 491; | ||||
| const prime3 = 487; | ||||
| const prime4 = 503; | ||||
| const minimumPictureBytes = 3 * prime4; | ||||
| class NeuQuant { | ||||
|     /** | ||||
|      * Creates the neural quantifier instance. | ||||
|      * @param pixels Array of pixels in RGB format, as such that it's decoded as `[r, g, b, r, g, b, r, g, b, ...]`. | ||||
|      * @param sampleFactorial Sampling factor from `1` to `30`, where lower is better quality. | ||||
|      */ | ||||
|     constructor(pixels, sampleFactorial) { | ||||
|         /** | ||||
|          * Array of pixels in RGB format, as such that it's decoded as `[r, g, b, r, g, b, r, g, b, ...]`. | ||||
|          */ | ||||
|         Object.defineProperty(this, "pixels", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         /** | ||||
|          * Sampling factor from `1` to `30`, where lower is better quality. | ||||
|          */ | ||||
|         Object.defineProperty(this, "sampleFactorial", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         /** | ||||
|          * The neural networks, composed by {@link maximumColorsSize} {@link Float64Array float arrays} of size 4. | ||||
|          */ | ||||
|         Object.defineProperty(this, "networks", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         /** | ||||
|          * Network lookup indexes, composed by 256 indexes. | ||||
|          */ | ||||
|         Object.defineProperty(this, "networkIndexes", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         // bias and freq arrays for learning
 | ||||
|         Object.defineProperty(this, "biases", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "frequencies", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         Object.defineProperty(this, "radiusPowers", { | ||||
|             enumerable: true, | ||||
|             configurable: true, | ||||
|             writable: true, | ||||
|             value: void 0 | ||||
|         }); | ||||
|         this.pixels = pixels; | ||||
|         this.sampleFactorial = sampleFactorial; | ||||
|         this.networks = []; | ||||
|         this.networkIndexes = new Int32Array(256); | ||||
|         this.biases = new Int32Array(maximumColorsSize); | ||||
|         this.frequencies = new Int32Array(maximumColorsSize); | ||||
|         this.radiusPowers = new Int32Array(maximumColorsSize >> 3); | ||||
|         this.init(); | ||||
|         this.learn(); | ||||
|         this.unBiasNetwork(); | ||||
|         this.buildIndexes(); | ||||
|     } | ||||
|     /** | ||||
|      * Builds the networks' color map. | ||||
|      * @returns A RGB-encoded {@link Float64Array}. | ||||
|      */ | ||||
|     getColorMap() { | ||||
|         const map = new Float64Array(maximumColorsSize * 3); | ||||
|         const index = new Float64Array(maximumColorsSize); | ||||
|         for (let i = 0; i < maximumColorsSize; i++) { | ||||
|             index[this.networks[i][3]] = i; | ||||
|         } | ||||
|         for (let l = 0, k = 0; l < maximumColorsSize; l++) { | ||||
|             const network = this.networks[index[l]]; | ||||
|             map[k++] = network[0]; | ||||
|             map[k++] = network[1]; | ||||
|             map[k++] = network[2]; | ||||
|         } | ||||
|         return map; | ||||
|     } | ||||
|     /** | ||||
|      * Searches for BGR values 0..255 and returns a color index | ||||
|      * @param b The blue color byte, between 0 and 255. | ||||
|      * @param g The green color byte, between 0 and 255. | ||||
|      * @param r The red color byte, between 0 and 255. | ||||
|      * @returns The best color index. | ||||
|      */ | ||||
|     lookupRGB(b, g, r) { | ||||
|         // Biggest possible distance is 256 * 3, so we will define the biggest as an out-of-bounds number.
 | ||||
|         let bestDistance = 1000; | ||||
|         let best = -1; | ||||
|         const index = this.networkIndexes[g]; | ||||
|         // Index on `g`
 | ||||
|         for (let i = index; i < maximumColorsSize; ++i) { | ||||
|             const network = this.networks[i]; | ||||
|             // Compare the distance of the green element, break if it's too big:
 | ||||
|             let distance = network[1] - g; | ||||
|             if (distance >= bestDistance) | ||||
|                 break; | ||||
|             // If `distance` is negative, make it positive:
 | ||||
|             if (distance < 0) | ||||
|                 distance = -distance; | ||||
|             // Compare the distance with the blue element added, continue if it's too big:
 | ||||
|             distance += Math.abs(network[0] - b); | ||||
|             if (distance >= bestDistance) | ||||
|                 continue; | ||||
|             // Compare the distance with the red element added, continue if it's too big:
 | ||||
|             distance += Math.abs(network[2] - r); | ||||
|             if (distance >= bestDistance) | ||||
|                 continue; | ||||
|             bestDistance = distance; | ||||
|             best = network[3]; | ||||
|         } | ||||
|         // Start at networkIndex[g] and work outwards
 | ||||
|         for (let j = index - 1; j >= 0; --j) { | ||||
|             const network = this.networks[j]; | ||||
|             // Compare the distance of the green element, break if it's too big:
 | ||||
|             let distance = g - network[1]; | ||||
|             if (distance >= bestDistance) | ||||
|                 break; | ||||
|             // If `distance` is negative, make it positive:
 | ||||
|             if (distance < 0) | ||||
|                 distance = -distance; | ||||
|             // Compare the distance with the blue element added, continue if it's too big:
 | ||||
|             distance += Math.abs(network[0] - b); | ||||
|             if (distance >= bestDistance) | ||||
|                 continue; | ||||
|             // Compare the distance with the red element added, continue if it's too big:
 | ||||
|             distance += Math.abs(network[2] - r); | ||||
|             if (distance >= bestDistance) | ||||
|                 continue; | ||||
|             bestDistance = distance; | ||||
|             best = network[3]; | ||||
|         } | ||||
|         return best; | ||||
|     } | ||||
|     /** | ||||
|      * Initializes the state for the arrays. | ||||
|      */ | ||||
|     init() { | ||||
|         for (let i = 0; i < maximumColorsSize; i++) { | ||||
|             const v = (i << (networkBiasShift + 8)) / maximumColorsSize; | ||||
|             this.networks[i] = new Float64Array([v, v, v, 0]); | ||||
|             this.frequencies[i] = integerBias / maximumColorsSize; | ||||
|             this.biases[i] = 0; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Un-biases network to give byte values 0..255 and record position i to prepare for sort. | ||||
|      */ | ||||
|     unBiasNetwork() { | ||||
|         for (let i = 0; i < maximumColorsSize; i++) { | ||||
|             const network = this.networks[i]; | ||||
|             network[0] >>= networkBiasShift; | ||||
|             network[1] >>= networkBiasShift; | ||||
|             network[2] >>= networkBiasShift; | ||||
|             network[3] = i; // record color number
 | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Moves neuron `i` towards biased (`B`, `G`, `R`) by factor `alpha`. | ||||
|      * @param alpha The factor at which the neuron `i` should move towards. | ||||
|      * @param i The neuron's index. | ||||
|      * @param b The blue color. | ||||
|      * @param g The green color. | ||||
|      * @param r The red color. | ||||
|      */ | ||||
|     alterSingle(alpha, i, b, g, r) { | ||||
|         const network = this.networks[i]; | ||||
|         network[0] -= (alpha * (network[0] - b)) / initialAlpha; | ||||
|         network[1] -= (alpha * (network[1] - g)) / initialAlpha; | ||||
|         network[2] -= (alpha * (network[2] - r)) / initialAlpha; | ||||
|     } | ||||
|     /** | ||||
|      * Moves neurons in a `radius` around index `i` towards biased (`B`, `G`, `R`) by factor | ||||
|      * {@link NeuQuant.radiusPowers `radiusPower[m]`}. | ||||
|      * @param radius The radius around `i` to alter. | ||||
|      * @param i The neuron's index. | ||||
|      * @param b The blue color. | ||||
|      * @param g The green color. | ||||
|      * @param r The red color. | ||||
|      */ | ||||
|     alterNeighbors(radius, i, b, g, r) { | ||||
|         const lo = Math.abs(i - radius); | ||||
|         const hi = Math.min(i + radius, maximumColorsSize); | ||||
|         let j = i + 1; | ||||
|         let k = i - 1; | ||||
|         let m = 1; | ||||
|         while (j < hi || k > lo) { | ||||
|             const alpha = this.radiusPowers[m++]; | ||||
|             if (j < hi) { | ||||
|                 const network = this.networks[j++]; | ||||
|                 network[0] -= (alpha * (network[0] - b)) / alphaRadiusBias; | ||||
|                 network[1] -= (alpha * (network[1] - g)) / alphaRadiusBias; | ||||
|                 network[2] -= (alpha * (network[2] - r)) / alphaRadiusBias; | ||||
|             } | ||||
|             if (k > lo) { | ||||
|                 const network = this.networks[k--]; | ||||
|                 network[0] -= (alpha * (network[0] - b)) / alphaRadiusBias; | ||||
|                 network[1] -= (alpha * (network[1] - g)) / alphaRadiusBias; | ||||
|                 network[2] -= (alpha * (network[2] - r)) / alphaRadiusBias; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Searches for biased BGR values. | ||||
|      * | ||||
|      * - Finds the closest neuron (minimum distance) and updates {@link NeuQuant.frequencies}. | ||||
|      * - Finds the best neuron (minimum distance-bias) and returns the position. | ||||
|      * | ||||
|      * For frequently chosen neurons, {@link NeuQuant.frequencies `frequencies[i]`} is high and | ||||
|      * {@link NeuQuant.biases `biases[i]`} is negative. | ||||
|      * | ||||
|      * The latter is determined by the multiplication of `gamma` with the subtraction of the inverse of | ||||
|      * {@link maximumColorsSize} with {@link NeuQuant.frequencies `frequencies[i]`}: | ||||
|      * | ||||
|      * ```typescript
 | ||||
|      * biases[i] = gamma * ((1 / maximumColorsSize) - frequencies[i]) | ||||
|      * ``` | ||||
|      * @param b The blue color. | ||||
|      * @param g The green color. | ||||
|      * @param r The red color. | ||||
|      * @returns The best bias position. | ||||
|      */ | ||||
|     contest(b, g, r) { | ||||
|         let bestDistance = ~(1 << 31); | ||||
|         let bestBiasDistance = bestDistance; | ||||
|         let bestPosition = -1; | ||||
|         let bestBiasPosition = bestPosition; | ||||
|         for (let i = 0; i < maximumColorsSize; i++) { | ||||
|             const network = this.networks[i]; | ||||
|             const distance = Math.abs(network[0] - b) + Math.abs(network[1] - g) + Math.abs(network[2] - r); | ||||
|             if (distance < bestDistance) { | ||||
|                 bestDistance = distance; | ||||
|                 bestPosition = i; | ||||
|             } | ||||
|             const biasDistance = distance - (this.biases[i] >> (integerBiasShift - networkBiasShift)); | ||||
|             if (biasDistance < bestBiasDistance) { | ||||
|                 bestBiasDistance = biasDistance; | ||||
|                 bestBiasPosition = i; | ||||
|             } | ||||
|             const betaFrequency = this.frequencies[i] >> betaShift; | ||||
|             this.frequencies[i] -= betaFrequency; | ||||
|             this.biases[i] += betaFrequency << gammaShift; | ||||
|         } | ||||
|         this.frequencies[bestPosition] += beta; | ||||
|         this.biases[bestPosition] -= betaGamma; | ||||
|         return bestBiasPosition; | ||||
|     } | ||||
|     /** | ||||
|      * Sorts the neural network and builds {@link NeuQuant.networkIndexes `networkIndex[0..255]`}. | ||||
|      */ | ||||
|     buildIndexes() { | ||||
|         let previousColor = 0; | ||||
|         let startPosition = 0; | ||||
|         for (let i = 0; i < maximumColorsSize; i++) { | ||||
|             const network = this.networks[i]; | ||||
|             let smallestPosition = i; | ||||
|             let smallestValue = network[1]; // index on g
 | ||||
|             // Find smallest in [i .. maximumColorsSize - 1]
 | ||||
|             for (let j = i + 1; j < maximumColorsSize; j++) { | ||||
|                 const q = this.networks[j]; | ||||
|                 if (q[1] < smallestValue) { | ||||
|                     smallestPosition = j; | ||||
|                     smallestValue = q[1]; // index on g
 | ||||
|                 } | ||||
|             } | ||||
|             // Swap network (i) and q (smallestPosition) entries:
 | ||||
|             if (i !== smallestPosition) { | ||||
|                 const q = this.networks[smallestPosition]; | ||||
|                 [q[0], network[0]] = [network[0], q[0]]; | ||||
|                 [q[1], network[1]] = [network[1], q[1]]; | ||||
|                 [q[2], network[2]] = [network[2], q[2]]; | ||||
|                 [q[3], network[3]] = [network[3], q[3]]; | ||||
|             } | ||||
|             // smallestValue entry is now in position i
 | ||||
|             if (smallestValue !== previousColor) { | ||||
|                 this.networkIndexes[previousColor] = (startPosition + i) >> 1; | ||||
|                 for (let j = previousColor + 1; j < smallestValue; j++) { | ||||
|                     this.networkIndexes[j] = i; | ||||
|                 } | ||||
|                 previousColor = smallestValue; | ||||
|                 startPosition = i; | ||||
|             } | ||||
|         } | ||||
|         this.networkIndexes[previousColor] = (startPosition + maximumColorsPosition) >> 1; | ||||
|         for (let j = previousColor + 1; j < 256; j++) { | ||||
|             this.networkIndexes[j] = maximumColorsPosition; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Runs the main learning loop. | ||||
|      */ | ||||
|     learn() { | ||||
|         const length = this.pixels.length; | ||||
|         const alphaDecrement = 30 + (this.sampleFactorial - 1) / 3; | ||||
|         const samplePixels = length / (3 * this.sampleFactorial); | ||||
|         let delta = ~~(samplePixels / learningCycles); | ||||
|         let alpha = initialAlpha; | ||||
|         let radius = initialRadius; | ||||
|         let localRadius = radius >> initialRadiusBiasShift; | ||||
|         if (localRadius <= 1) | ||||
|             localRadius = 0; | ||||
|         for (let i = 0; i < localRadius; i++) { | ||||
|             this.radiusPowers[i] = alpha * (((localRadius * localRadius - i * i) * radiusBias) / (localRadius * localRadius)); | ||||
|         } | ||||
|         let step; | ||||
|         if (length < minimumPictureBytes) { | ||||
|             this.sampleFactorial = 1; | ||||
|             step = 3; | ||||
|         } | ||||
|         else if (length % prime1 !== 0) { | ||||
|             step = 3 * prime1; | ||||
|         } | ||||
|         else if (length % prime2 !== 0) { | ||||
|             step = 3 * prime2; | ||||
|         } | ||||
|         else if (length % prime3 !== 0) { | ||||
|             step = 3 * prime3; | ||||
|         } | ||||
|         else { | ||||
|             step = 3 * prime4; | ||||
|         } | ||||
|         let pixelPosition = 0; | ||||
|         let i = 0; | ||||
|         while (i < samplePixels) { | ||||
|             const b = (this.pixels[pixelPosition] & 0xff) << networkBiasShift; | ||||
|             const g = (this.pixels[pixelPosition + 1] & 0xff) << networkBiasShift; | ||||
|             const r = (this.pixels[pixelPosition + 2] & 0xff) << networkBiasShift; | ||||
|             let j = this.contest(b, g, r); | ||||
|             this.alterSingle(alpha, j, b, g, r); | ||||
|             if (localRadius !== 0) | ||||
|                 this.alterNeighbors(localRadius, j, b, g, r); | ||||
|             pixelPosition += step; | ||||
|             if (pixelPosition >= length) | ||||
|                 pixelPosition -= length; | ||||
|             if (delta === 0) | ||||
|                 delta = 1; | ||||
|             ++i; | ||||
|             if (i % delta !== 0) | ||||
|                 continue; | ||||
|             alpha -= alpha / alphaDecrement; | ||||
|             radius -= radius / initialRadiusDecrement; | ||||
|             localRadius = radius >> initialRadiusBiasShift; | ||||
|             if (localRadius <= 1) | ||||
|                 localRadius = 0; | ||||
|             for (j = 0; j < localRadius; j++) { | ||||
|                 this.radiusPowers[j] = alpha * (((localRadius * localRadius - j * j) * radiusBias) / (localRadius * localRadius)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| exports.NeuQuant = NeuQuant; | ||||
| //# sourceMappingURL=NeuQuant.js.map
 | ||||
							
								
								
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/@skyra/gifenc/dist/lib/NeuQuant.js.map
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										104
									
								
								node_modules/@skyra/gifenc/package.json
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								node_modules/@skyra/gifenc/package.json
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,104 @@ | |||
| { | ||||
|   "name": "@skyra/gifenc", | ||||
|   "version": "1.0.1", | ||||
|   "description": "A very fast server-side animated GIF generation for Node.js", | ||||
|   "author": "@skyra", | ||||
|   "license": "MIT", | ||||
|   "main": "dist/index.js", | ||||
|   "module": "dist/index.mjs", | ||||
|   "types": "dist/index.d.ts", | ||||
|   "exports": { | ||||
|     "import": "./dist/index.mjs", | ||||
|     "require": "./dist/index.js", | ||||
|     "types": "./dist/index.d.ts" | ||||
|   }, | ||||
|   "sideEffects": false, | ||||
|   "homepage": "https://skyra-project.github.io/gifenc", | ||||
|   "files": [ | ||||
|     "dist", | ||||
|     "!dist/tsconfig.tsbuildinfo" | ||||
|   ], | ||||
|   "scripts": { | ||||
|     "lint": "eslint src --ext ts --fix", | ||||
|     "format": "prettier --write \"{src}/**/*.ts\"", | ||||
|     "docs": "typedoc", | ||||
|     "update": "yarn up \"@*/*\" -i && yarn up \"*\" -i", | ||||
|     "build": "tsc -b src && gen-esm-wrapper dist/index.js dist/index.mjs", | ||||
|     "watch": "yarn build -w", | ||||
|     "clean": "node scripts/clean-dist.mjs", | ||||
|     "sversion": "standard-version", | ||||
|     "prepublishOnly": "yarn clean && yarn build", | ||||
|     "prepare": "husky install .github/husky" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "tslib": "^2.4.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@commitlint/cli": "^17.1.2", | ||||
|     "@commitlint/config-conventional": "^17.1.0", | ||||
|     "@sapphire/eslint-config": "^4.3.8", | ||||
|     "@sapphire/prettier-config": "^1.4.4", | ||||
|     "@sapphire/ts-config": "^3.3.4", | ||||
|     "@types/jest": "^29.2.0", | ||||
|     "@types/node": "^17.0.18", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.40.1", | ||||
|     "@typescript-eslint/parser": "^5.40.1", | ||||
|     "cz-conventional-changelog": "^3.3.0", | ||||
|     "eslint": "^8.26.0", | ||||
|     "eslint-config-prettier": "^8.5.0", | ||||
|     "eslint-plugin-prettier": "^4.2.1", | ||||
|     "gen-esm-wrapper": "^1.1.3", | ||||
|     "husky": "^8.0.1", | ||||
|     "lint-staged": "^13.0.3", | ||||
|     "prettier": "^2.7.1", | ||||
|     "pretty-quick": "^3.1.3", | ||||
|     "standard-version": "^9.3.2", | ||||
|     "typedoc": "^0.23.17", | ||||
|     "typescript": "^4.8.4" | ||||
|   }, | ||||
|   "resolutions": { | ||||
|     "ansi-regex": "^5.0.1", | ||||
|     "minimist": "^1.2.7" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "git+https://github.com/skyra-project/gifenc.git" | ||||
|   }, | ||||
|   "engines": { | ||||
|     "node": ">=v14.18.0", | ||||
|     "npm": ">=7.24.2" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "typescript", | ||||
|     "ts", | ||||
|     "yarn", | ||||
|     "gif", | ||||
|     "gifenc", | ||||
|     "encoder", | ||||
|     "utility" | ||||
|   ], | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/skyra-project/gifenc/issues" | ||||
|   }, | ||||
|   "commitlint": { | ||||
|     "extends": [ | ||||
|       "@commitlint/config-conventional" | ||||
|     ] | ||||
|   }, | ||||
|   "lint-staged": { | ||||
|     "*.{mjs,js,ts}": "eslint --fix --ext mjs,js,ts" | ||||
|   }, | ||||
|   "config": { | ||||
|     "commitizen": { | ||||
|       "path": "./node_modules/cz-conventional-changelog" | ||||
|     } | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   }, | ||||
|   "eslintConfig": { | ||||
|     "extends": "@sapphire" | ||||
|   }, | ||||
|   "prettier": "@sapphire/prettier-config", | ||||
|   "packageManager": "yarn@3.2.4" | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue