1
0
Fork 0
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:
koelo 2022-12-03 05:44:44 +00:00
parent a5a0523e5a
commit 3513d5390c
2016 changed files with 336930 additions and 9 deletions

3
node_modules/@skyra/gifenc/dist/index.d.ts generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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

View file

@ -0,0 +1 @@
{"version":3,"file":"ByteBuffer.js","sourceRoot":"","sources":["../../src/lib/ByteBuffer.ts"],"names":[],"mappings":"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"}

279
node_modules/@skyra/gifenc/dist/lib/GifEncoder.d.ts generated vendored Normal file
View 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

View file

@ -0,0 +1 @@
{"version":3,"file":"GifEncoder.d.ts","sourceRoot":"","sources":["../../src/lib/GifEncoder.ts"],"names":[],"mappings":"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"}

562
node_modules/@skyra/gifenc/dist/lib/GifEncoder.js generated vendored Normal file
View 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

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
View 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

View 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
View 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

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
View 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

View 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
View 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

File diff suppressed because one or more lines are too long