mirror of
https://github.com/0x5eal/rbxts-pako.git
synced 2025-04-10 22:00:58 +01:00
add ts types, port to using luau apis
This commit is contained in:
parent
cf8e6ba0f7
commit
20d3146428
16 changed files with 5235 additions and 5224 deletions
181
src/deflate.ts
181
src/deflate.ts
|
@ -1,28 +1,29 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { DeflateState } from "./zlib/deflate";
|
||||||
const zlib_deflate = require('./zlib/deflate');
|
import * as zlibDeflate from "./zlib/deflate";
|
||||||
const utils = require('./utils/common');
|
import { ZStream } from "./zlib/zstream";
|
||||||
const strings = require('./utils/strings');
|
|
||||||
const msg = require('./zlib/messages');
|
|
||||||
const ZStream = require('./zlib/zstream');
|
|
||||||
|
|
||||||
const toString = Object.prototype.toString;
|
|
||||||
|
|
||||||
/* Public constants ==========================================================*/
|
/* Public constants ==========================================================*/
|
||||||
/* ===========================================================================*/
|
/* ===========================================================================*/
|
||||||
|
|
||||||
const {
|
import {
|
||||||
Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH,
|
Z_NO_FLUSH,
|
||||||
Z_OK, Z_STREAM_END,
|
Z_SYNC_FLUSH,
|
||||||
|
Z_FULL_FLUSH,
|
||||||
|
Z_FINISH,
|
||||||
|
Z_OK,
|
||||||
|
Z_STREAM_END,
|
||||||
Z_DEFAULT_COMPRESSION,
|
Z_DEFAULT_COMPRESSION,
|
||||||
Z_DEFAULT_STRATEGY,
|
Z_DEFAULT_STRATEGY,
|
||||||
Z_DEFLATED
|
Z_DEFLATED,
|
||||||
} = require('./zlib/constants');
|
} from "./zlib/constants";
|
||||||
|
import { assign, flattenChunks } from "./utils/common";
|
||||||
|
import { Uint8Array } from "./utils/buffs";
|
||||||
|
import messages from "./zlib/messages";
|
||||||
|
|
||||||
/* ===========================================================================*/
|
/* ===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class Deflate
|
* class Deflate
|
||||||
*
|
*
|
||||||
|
@ -60,7 +61,6 @@ const {
|
||||||
* Error message, if [[Deflate.err]] != 0
|
* Error message, if [[Deflate.err]] != 0
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* new Deflate(options)
|
* new Deflate(options)
|
||||||
* - options (Object): zlib deflate options.
|
* - options (Object): zlib deflate options.
|
||||||
|
@ -108,70 +108,87 @@ const {
|
||||||
* console.log(deflate.result);
|
* console.log(deflate.result);
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
function Deflate(options) {
|
|
||||||
this.options = utils.assign({
|
type Options = {
|
||||||
|
level: number;
|
||||||
|
method: number;
|
||||||
|
chunkSize: number;
|
||||||
|
windowBits: number;
|
||||||
|
memLevel: number;
|
||||||
|
strategy: number;
|
||||||
|
raw: boolean;
|
||||||
|
gzip: boolean;
|
||||||
|
header?: DeflateState["gzhead"];
|
||||||
|
dictionary?: Uint8Array | string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class Deflate {
|
||||||
|
public options: Exclude<Options, "dictionary"> & { dictionary?: Uint8Array };
|
||||||
|
public err: keyof typeof messages = Z_OK;
|
||||||
|
public msg?: string;
|
||||||
|
public ended = false;
|
||||||
|
public chunks: Uint8Array[] = [];
|
||||||
|
public strm = new ZStream<DeflateState>();
|
||||||
|
public result?: buffer;
|
||||||
|
|
||||||
|
constructor(options: Partial<Options>) {
|
||||||
|
this.options = assign(
|
||||||
|
{
|
||||||
level: Z_DEFAULT_COMPRESSION,
|
level: Z_DEFAULT_COMPRESSION,
|
||||||
method: Z_DEFLATED,
|
method: Z_DEFLATED,
|
||||||
chunkSize: 16384,
|
chunkSize: 16384,
|
||||||
windowBits: 15,
|
windowBits: 15,
|
||||||
memLevel: 8,
|
memLevel: 8,
|
||||||
strategy: Z_DEFAULT_STRATEGY
|
strategy: Z_DEFAULT_STRATEGY,
|
||||||
}, options || {});
|
raw: false,
|
||||||
|
gzip: false,
|
||||||
|
},
|
||||||
|
options || {},
|
||||||
|
) as unknown as typeof this.options;
|
||||||
|
|
||||||
let opt = this.options;
|
let opt = this.options;
|
||||||
|
|
||||||
if (opt.raw && (opt.windowBits > 0)) {
|
if (opt.raw && opt.windowBits > 0) {
|
||||||
opt.windowBits = -opt.windowBits;
|
opt.windowBits = -opt.windowBits;
|
||||||
}
|
} else if (opt.gzip && opt.windowBits > 0 && opt.windowBits < 16) {
|
||||||
|
|
||||||
else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
|
|
||||||
opt.windowBits += 16;
|
opt.windowBits += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.err = 0; // error code, if happens (0 = Z_OK)
|
if (opt.dictionary) {
|
||||||
this.msg = ''; // error message
|
// Convert data if needed
|
||||||
this.ended = false; // used to avoid multiple onEnd() calls
|
let dict = opt.dictionary;
|
||||||
this.chunks = []; // chunks of compressed data
|
if (typeIs(dict, "string")) {
|
||||||
|
dict = Uint8Array.from(buffer.fromstring(dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
opt.dictionary = dict;
|
||||||
|
}
|
||||||
|
|
||||||
this.strm = new ZStream();
|
|
||||||
this.strm.avail_out = 0;
|
this.strm.avail_out = 0;
|
||||||
|
|
||||||
let status = zlib_deflate.deflateInit2(
|
const status = zlibDeflate.deflateInit2(
|
||||||
this.strm,
|
this.strm,
|
||||||
opt.level,
|
opt.level,
|
||||||
opt.method,
|
opt.method,
|
||||||
opt.windowBits,
|
opt.windowBits,
|
||||||
opt.memLevel,
|
opt.memLevel,
|
||||||
opt.strategy
|
opt.strategy,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (status !== Z_OK) {
|
if (status !== Z_OK) {
|
||||||
throw new Error(msg[status]);
|
error(messages[status]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.header) {
|
if (opt.header) {
|
||||||
zlib_deflate.deflateSetHeader(this.strm, opt.header);
|
zlibDeflate.deflateSetHeader(this.strm, opt.header);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.dictionary) {
|
if (opt.dictionary) {
|
||||||
let dict;
|
const status = zlibDeflate.deflateSetDictionary(this.strm, opt.dictionary);
|
||||||
// Convert data if needed
|
|
||||||
if (typeof opt.dictionary === 'string') {
|
|
||||||
// If we need to compress text, change encoding to utf8.
|
|
||||||
dict = strings.string2buf(opt.dictionary);
|
|
||||||
} else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
|
|
||||||
dict = new Uint8Array(opt.dictionary);
|
|
||||||
} else {
|
|
||||||
dict = opt.dictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = zlib_deflate.deflateSetDictionary(this.strm, dict);
|
|
||||||
|
|
||||||
if (status !== Z_OK) {
|
if (status !== Z_OK) {
|
||||||
throw new Error(msg[status]);
|
error(messages[status]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dict_set = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,24 +214,21 @@ function Deflate(options) {
|
||||||
* push(chunk, true); // push last chunk
|
* push(chunk, true); // push last chunk
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
Deflate.prototype.push = function (data, flush_mode) {
|
push(data: Uint8Array | string, flush_mode: boolean | number) {
|
||||||
const strm = this.strm;
|
const strm = this.strm;
|
||||||
const chunkSize = this.options.chunkSize;
|
const { chunkSize } = this.options;
|
||||||
let status, _flush_mode;
|
let status, _flush_mode;
|
||||||
|
|
||||||
if (this.ended) { return false; }
|
if (this.ended) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;
|
if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;
|
||||||
else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH;
|
else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH;
|
||||||
|
|
||||||
// Convert data if needed
|
// Convert data if needed
|
||||||
if (typeof data === 'string') {
|
if (typeIs(data, "string")) {
|
||||||
// If we need to compress text, change encoding to utf8.
|
strm.input = Uint8Array.from(buffer.fromstring(data));
|
||||||
strm.input = strings.string2buf(data);
|
|
||||||
} else if (toString.call(data) === '[object ArrayBuffer]') {
|
|
||||||
strm.input = new Uint8Array(data);
|
|
||||||
} else {
|
|
||||||
strm.input = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
strm.next_in = 0;
|
strm.next_in = 0;
|
||||||
|
@ -234,14 +248,14 @@ Deflate.prototype.push = function (data, flush_mode) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = zlib_deflate.deflate(strm, _flush_mode);
|
status = zlibDeflate.deflate(strm, _flush_mode);
|
||||||
|
|
||||||
// Ended => flush and finish
|
// Ended => flush and finish
|
||||||
if (status === Z_STREAM_END) {
|
if (status === Z_STREAM_END) {
|
||||||
if (strm.next_out > 0) {
|
if (strm.next_out > 0) {
|
||||||
this.onData(strm.output.subarray(0, strm.next_out));
|
this.onData(strm.output.subarray(0, strm.next_out));
|
||||||
}
|
}
|
||||||
status = zlib_deflate.deflateEnd(this.strm);
|
const status = zlibDeflate.deflateEnd(this.strm);
|
||||||
this.onEnd(status);
|
this.onEnd(status);
|
||||||
this.ended = true;
|
this.ended = true;
|
||||||
return status === Z_OK;
|
return status === Z_OK;
|
||||||
|
@ -264,8 +278,7 @@ Deflate.prototype.push = function (data, flush_mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deflate#onData(chunk) -> Void
|
* Deflate#onData(chunk) -> Void
|
||||||
|
@ -274,10 +287,9 @@ Deflate.prototype.push = function (data, flush_mode) {
|
||||||
* By default, stores data blocks in `chunks[]` property and glue
|
* By default, stores data blocks in `chunks[]` property and glue
|
||||||
* those in `onEnd`. Override this handler, if you need another behaviour.
|
* those in `onEnd`. Override this handler, if you need another behaviour.
|
||||||
**/
|
**/
|
||||||
Deflate.prototype.onData = function (chunk) {
|
onData(chunk: Uint8Array) {
|
||||||
this.chunks.push(chunk);
|
this.chunks.push(chunk);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deflate#onEnd(status) -> Void
|
* Deflate#onEnd(status) -> Void
|
||||||
|
@ -288,16 +300,16 @@ Deflate.prototype.onData = function (chunk) {
|
||||||
* complete (Z_FINISH). By default - join collected chunks,
|
* complete (Z_FINISH). By default - join collected chunks,
|
||||||
* free memory and fill `results` / `err` properties.
|
* free memory and fill `results` / `err` properties.
|
||||||
**/
|
**/
|
||||||
Deflate.prototype.onEnd = function (status) {
|
onEnd(status: keyof typeof messages) {
|
||||||
// On success - join
|
// On success - join
|
||||||
if (status === Z_OK) {
|
if (status === Z_OK) {
|
||||||
this.result = utils.flattenChunks(this.chunks);
|
this.result = flattenChunks(this.chunks.map((chunk) => chunk.buf));
|
||||||
}
|
}
|
||||||
this.chunks = [];
|
this.chunks = [];
|
||||||
this.err = status;
|
this.err = status;
|
||||||
this.msg = this.strm.msg;
|
this.msg = this.strm.msg;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deflate(data[, options]) -> Uint8Array
|
* deflate(data[, options]) -> Uint8Array
|
||||||
|
@ -331,18 +343,19 @@ Deflate.prototype.onEnd = function (status) {
|
||||||
* console.log(pako.deflate(data));
|
* console.log(pako.deflate(data));
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
function deflate(input, options) {
|
export function deflate(input: Uint8Array, options: Partial<Options> = {}) {
|
||||||
const deflator = new Deflate(options);
|
const deflator = new Deflate(options);
|
||||||
|
|
||||||
deflator.push(input, true);
|
deflator.push(input, true);
|
||||||
|
|
||||||
// That will never happens, if you don't cheat with options :)
|
// That will never happens, if you don't cheat with options :)
|
||||||
if (deflator.err) { throw deflator.msg || msg[deflator.err]; }
|
if (deflator.err) {
|
||||||
|
error(deflator.msg || messages[deflator.err]);
|
||||||
|
}
|
||||||
|
|
||||||
return deflator.result;
|
return deflator.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deflateRaw(data[, options]) -> Uint8Array
|
* deflateRaw(data[, options]) -> Uint8Array
|
||||||
* - data (Uint8Array|ArrayBuffer|String): input data to compress.
|
* - data (Uint8Array|ArrayBuffer|String): input data to compress.
|
||||||
|
@ -351,30 +364,10 @@ function deflate(input, options) {
|
||||||
* The same as [[deflate]], but creates raw data, without wrapper
|
* The same as [[deflate]], but creates raw data, without wrapper
|
||||||
* (header and adler32 crc).
|
* (header and adler32 crc).
|
||||||
**/
|
**/
|
||||||
function deflateRaw(input, options) {
|
export function deflateRaw(input: Uint8Array, options: Exclude<Partial<Options>, "raw"> = {}) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.raw = true;
|
options.raw = true;
|
||||||
return deflate(input, options);
|
return deflate(input, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * from "./zlib/constants";
|
||||||
/**
|
|
||||||
* gzip(data[, options]) -> Uint8Array
|
|
||||||
* - data (Uint8Array|ArrayBuffer|String): input data to compress.
|
|
||||||
* - options (Object): zlib deflate options.
|
|
||||||
*
|
|
||||||
* The same as [[deflate]], but create gzip wrapper instead of
|
|
||||||
* deflate one.
|
|
||||||
**/
|
|
||||||
function gzip(input, options) {
|
|
||||||
options = options || {};
|
|
||||||
options.gzip = true;
|
|
||||||
return deflate(input, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.Deflate = Deflate;
|
|
||||||
module.exports.deflate = deflate;
|
|
||||||
module.exports.deflateRaw = deflateRaw;
|
|
||||||
module.exports.gzip = gzip;
|
|
||||||
module.exports.constants = require('./zlib/constants');
|
|
||||||
|
|
226
src/inflate.ts
226
src/inflate.ts
|
@ -1,26 +1,29 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { type InflateState } from "./zlib/inflate";
|
||||||
const zlib_inflate = require('./zlib/inflate');
|
import * as zlibInflate from "./zlib/inflate";
|
||||||
const utils = require('./utils/common');
|
import { ZStream } from "./zlib/zstream";
|
||||||
const strings = require('./utils/strings');
|
import { GZheader } from "./zlib/gzheader";
|
||||||
const msg = require('./zlib/messages');
|
|
||||||
const ZStream = require('./zlib/zstream');
|
|
||||||
const GZheader = require('./zlib/gzheader');
|
|
||||||
|
|
||||||
const toString = Object.prototype.toString;
|
|
||||||
|
|
||||||
/* Public constants ==========================================================*/
|
/* Public constants ==========================================================*/
|
||||||
/* ===========================================================================*/
|
/* ===========================================================================*/
|
||||||
|
|
||||||
const {
|
import {
|
||||||
Z_NO_FLUSH, Z_FINISH,
|
Z_NO_FLUSH,
|
||||||
Z_OK, Z_STREAM_END, Z_NEED_DICT, Z_STREAM_ERROR, Z_DATA_ERROR, Z_MEM_ERROR
|
Z_FINISH,
|
||||||
} = require('./zlib/constants');
|
Z_OK,
|
||||||
|
Z_STREAM_END,
|
||||||
|
Z_NEED_DICT,
|
||||||
|
Z_STREAM_ERROR,
|
||||||
|
Z_DATA_ERROR,
|
||||||
|
Z_MEM_ERROR,
|
||||||
|
} from "./zlib/constants";
|
||||||
|
import { Uint8Array } from "./utils/buffs";
|
||||||
|
import { assign, flattenChunks } from "./utils/common";
|
||||||
|
import messages from "./zlib/messages";
|
||||||
|
|
||||||
/* ===========================================================================*/
|
/* ===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class Inflate
|
* class Inflate
|
||||||
*
|
*
|
||||||
|
@ -56,7 +59,6 @@ const {
|
||||||
* Error message, if [[Inflate.err]] != 0
|
* Error message, if [[Inflate.err]] != 0
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* new Inflate(options)
|
* new Inflate(options)
|
||||||
* - options (Object): zlib inflate options.
|
* - options (Object): zlib inflate options.
|
||||||
|
@ -98,31 +100,56 @@ const {
|
||||||
* console.log(inflate.result);
|
* console.log(inflate.result);
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
function Inflate(options) {
|
|
||||||
this.options = utils.assign({
|
type Options = {
|
||||||
|
chunkSize: number;
|
||||||
|
windowBits: number;
|
||||||
|
to: string;
|
||||||
|
raw: boolean;
|
||||||
|
dictionary?: string | Uint8Array;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class Inflate {
|
||||||
|
public options: Exclude<Options, "dictionary"> & { dictionary?: Uint8Array };
|
||||||
|
public err: keyof typeof messages = Z_OK;
|
||||||
|
public msg?: string;
|
||||||
|
public ended = false;
|
||||||
|
public chunks: Uint8Array[] = [];
|
||||||
|
public strm = new ZStream<InflateState>();
|
||||||
|
public header = new GZheader();
|
||||||
|
public result?: buffer | string;
|
||||||
|
|
||||||
|
constructor(options?: Partial<Options>) {
|
||||||
|
this.options = assign(
|
||||||
|
{
|
||||||
chunkSize: 1024 * 64,
|
chunkSize: 1024 * 64,
|
||||||
windowBits: 15,
|
windowBits: 15,
|
||||||
to: ''
|
to: "",
|
||||||
}, options || {});
|
raw: false,
|
||||||
|
dictionary: undefined,
|
||||||
|
},
|
||||||
|
options ?? {},
|
||||||
|
) as unknown as typeof this.options;
|
||||||
|
|
||||||
const opt = this.options;
|
const opt = this.options;
|
||||||
|
|
||||||
// Force window size for `raw` data, if not set directly,
|
// Force window size for `raw` data, if not set directly,
|
||||||
// because we have no header for autodetect.
|
// because we have no header for autodetect.
|
||||||
if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
|
if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) {
|
||||||
opt.windowBits = -opt.windowBits;
|
opt.windowBits = -opt.windowBits;
|
||||||
if (opt.windowBits === 0) { opt.windowBits = -15; }
|
if (opt.windowBits === 0) {
|
||||||
|
opt.windowBits = -15;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
|
// If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
|
||||||
if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
|
if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) {
|
||||||
!(options && options.windowBits)) {
|
|
||||||
opt.windowBits += 32;
|
opt.windowBits += 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gzip header has no info about windows size, we can do autodetect only
|
// Gzip header has no info about windows size, we can do autodetect only
|
||||||
// for deflate. So, if window size not set, force it to max when gzip possible
|
// for deflate. So, if window size not set, force it to max when gzip possible
|
||||||
if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
|
if (opt.windowBits > 15 && opt.windowBits < 48) {
|
||||||
// bit 3 (16) -> gzipped data
|
// bit 3 (16) -> gzipped data
|
||||||
// bit 4 (32) -> autodetect gzip/deflate
|
// bit 4 (32) -> autodetect gzip/deflate
|
||||||
if ((opt.windowBits & 15) === 0) {
|
if ((opt.windowBits & 15) === 0) {
|
||||||
|
@ -130,40 +157,32 @@ function Inflate(options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.err = 0; // error code, if happens (0 = Z_OK)
|
|
||||||
this.msg = ''; // error message
|
|
||||||
this.ended = false; // used to avoid multiple onEnd() calls
|
|
||||||
this.chunks = []; // chunks of compressed data
|
|
||||||
|
|
||||||
this.strm = new ZStream();
|
|
||||||
this.strm.avail_out = 0;
|
|
||||||
|
|
||||||
let status = zlib_inflate.inflateInit2(
|
|
||||||
this.strm,
|
|
||||||
opt.windowBits
|
|
||||||
);
|
|
||||||
|
|
||||||
if (status !== Z_OK) {
|
|
||||||
throw new Error(msg[status]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.header = new GZheader();
|
|
||||||
|
|
||||||
zlib_inflate.inflateGetHeader(this.strm, this.header);
|
|
||||||
|
|
||||||
// Setup dictionary
|
|
||||||
if (opt.dictionary) {
|
if (opt.dictionary) {
|
||||||
// Convert data if needed
|
// Convert data if needed
|
||||||
if (typeof opt.dictionary === 'string') {
|
let dict = opt.dictionary;
|
||||||
opt.dictionary = strings.string2buf(opt.dictionary);
|
if (typeIs(dict, "string")) {
|
||||||
} else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {
|
dict = Uint8Array.from(buffer.fromstring(dict));
|
||||||
opt.dictionary = new Uint8Array(opt.dictionary);
|
|
||||||
}
|
}
|
||||||
if (opt.raw) { //In raw mode we need to set the dictionary early
|
|
||||||
status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary);
|
opt.dictionary = dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.strm.avail_out = 0;
|
||||||
|
|
||||||
|
const { windowBits, dictionary, raw } = opt;
|
||||||
|
const status = zlibInflate.inflateInit2(this.strm, windowBits);
|
||||||
|
|
||||||
if (status !== Z_OK) {
|
if (status !== Z_OK) {
|
||||||
throw new Error(msg[status]);
|
error(messages[status]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zlibInflate.inflateGetHeader(this.strm, this.header);
|
||||||
|
|
||||||
|
if (dictionary && raw) {
|
||||||
|
//In raw mode we need to set the dictionary early
|
||||||
|
const status = zlibInflate.inflateSetDictionary(this.strm, dictionary);
|
||||||
|
if (status !== Z_OK) {
|
||||||
|
error(messages[status]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,10 +212,9 @@ function Inflate(options) {
|
||||||
* push(chunk, true); // push last chunk
|
* push(chunk, true); // push last chunk
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
Inflate.prototype.push = function (data, flush_mode) {
|
push(data: Uint8Array, flush_mode: number | boolean) {
|
||||||
const strm = this.strm;
|
const strm = this.strm;
|
||||||
const chunkSize = this.options.chunkSize;
|
const { chunkSize, dictionary } = this.options;
|
||||||
const dictionary = this.options.dictionary;
|
|
||||||
let status, _flush_mode, last_avail_out;
|
let status, _flush_mode, last_avail_out;
|
||||||
|
|
||||||
if (this.ended) return false;
|
if (this.ended) return false;
|
||||||
|
@ -204,12 +222,7 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;
|
if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;
|
||||||
else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH;
|
else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH;
|
||||||
|
|
||||||
// Convert data if needed
|
|
||||||
if (toString.call(data) === '[object ArrayBuffer]') {
|
|
||||||
strm.input = new Uint8Array(data);
|
|
||||||
} else {
|
|
||||||
strm.input = data;
|
strm.input = data;
|
||||||
}
|
|
||||||
|
|
||||||
strm.next_in = 0;
|
strm.next_in = 0;
|
||||||
strm.avail_in = strm.input.length;
|
strm.avail_in = strm.input.length;
|
||||||
|
@ -221,13 +234,13 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
strm.avail_out = chunkSize;
|
strm.avail_out = chunkSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = zlib_inflate.inflate(strm, _flush_mode);
|
status = zlibInflate.inflate(strm, _flush_mode);
|
||||||
|
|
||||||
if (status === Z_NEED_DICT && dictionary) {
|
if (status === Z_NEED_DICT && dictionary) {
|
||||||
status = zlib_inflate.inflateSetDictionary(strm, dictionary);
|
status = zlibInflate.inflateSetDictionary(strm, dictionary);
|
||||||
|
|
||||||
if (status === Z_OK) {
|
if (status === Z_OK) {
|
||||||
status = zlib_inflate.inflate(strm, _flush_mode);
|
status = zlibInflate.inflate(strm, _flush_mode);
|
||||||
} else if (status === Z_DATA_ERROR) {
|
} else if (status === Z_DATA_ERROR) {
|
||||||
// Replace code with more verbose
|
// Replace code with more verbose
|
||||||
status = Z_NEED_DICT;
|
status = Z_NEED_DICT;
|
||||||
|
@ -235,13 +248,9 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip snyc markers if more data follows and not raw mode
|
// Skip snyc markers if more data follows and not raw mode
|
||||||
while (strm.avail_in > 0 &&
|
while (strm.avail_in > 0 && status === Z_STREAM_END && strm.state.wrap > 0 && data[strm.next_in] !== 0) {
|
||||||
status === Z_STREAM_END &&
|
zlibInflate.inflateReset(strm);
|
||||||
strm.state.wrap > 0 &&
|
status = zlibInflate.inflate(strm, _flush_mode);
|
||||||
data[strm.next_in] !== 0)
|
|
||||||
{
|
|
||||||
zlib_inflate.inflateReset(strm);
|
|
||||||
status = zlib_inflate.inflate(strm, _flush_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -258,27 +267,10 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
// to align utf8 strings boundaries.
|
// to align utf8 strings boundaries.
|
||||||
last_avail_out = strm.avail_out;
|
last_avail_out = strm.avail_out;
|
||||||
|
|
||||||
if (strm.next_out) {
|
if (strm.next_out && (strm.avail_out === 0 || status === Z_STREAM_END)) {
|
||||||
if (strm.avail_out === 0 || status === Z_STREAM_END) {
|
this.onData(
|
||||||
|
strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out),
|
||||||
if (this.options.to === 'string') {
|
);
|
||||||
|
|
||||||
let next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
|
|
||||||
|
|
||||||
let tail = strm.next_out - next_out_utf8;
|
|
||||||
let utf8str = strings.buf2string(strm.output, next_out_utf8);
|
|
||||||
|
|
||||||
// move tail & realign counters
|
|
||||||
strm.next_out = tail;
|
|
||||||
strm.avail_out = chunkSize - tail;
|
|
||||||
if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0);
|
|
||||||
|
|
||||||
this.onData(utf8str);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must repeat iteration if out buffer is full
|
// Must repeat iteration if out buffer is full
|
||||||
|
@ -286,7 +278,7 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
|
|
||||||
// Finalize if end of stream reached.
|
// Finalize if end of stream reached.
|
||||||
if (status === Z_STREAM_END) {
|
if (status === Z_STREAM_END) {
|
||||||
status = zlib_inflate.inflateEnd(this.strm);
|
const status = zlibInflate.inflateEnd(this.strm);
|
||||||
this.onEnd(status);
|
this.onEnd(status);
|
||||||
this.ended = true;
|
this.ended = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -296,8 +288,7 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inflate#onData(chunk) -> Void
|
* Inflate#onData(chunk) -> Void
|
||||||
|
@ -307,10 +298,9 @@ Inflate.prototype.push = function (data, flush_mode) {
|
||||||
* By default, stores data blocks in `chunks[]` property and glue
|
* By default, stores data blocks in `chunks[]` property and glue
|
||||||
* those in `onEnd`. Override this handler, if you need another behaviour.
|
* those in `onEnd`. Override this handler, if you need another behaviour.
|
||||||
**/
|
**/
|
||||||
Inflate.prototype.onData = function (chunk) {
|
onData(chunk: Uint8Array) {
|
||||||
this.chunks.push(chunk);
|
this.chunks.push(chunk);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inflate#onEnd(status) -> Void
|
* Inflate#onEnd(status) -> Void
|
||||||
|
@ -321,20 +311,20 @@ Inflate.prototype.onData = function (chunk) {
|
||||||
* complete (Z_FINISH). By default - join collected chunks,
|
* complete (Z_FINISH). By default - join collected chunks,
|
||||||
* free memory and fill `results` / `err` properties.
|
* free memory and fill `results` / `err` properties.
|
||||||
**/
|
**/
|
||||||
Inflate.prototype.onEnd = function (status) {
|
onEnd(status: keyof typeof messages) {
|
||||||
// On success - join
|
// On success - join
|
||||||
if (status === Z_OK) {
|
if (status === Z_OK) {
|
||||||
if (this.options.to === 'string') {
|
if (this.options.to === "string") {
|
||||||
this.result = this.chunks.join('');
|
this.result = this.chunks.join("");
|
||||||
} else {
|
} else {
|
||||||
this.result = utils.flattenChunks(this.chunks);
|
this.result = flattenChunks(this.chunks.map((chunk) => chunk.buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.chunks = [];
|
this.chunks = [];
|
||||||
this.err = status;
|
this.err = status;
|
||||||
this.msg = this.strm.msg;
|
this.msg = this.strm.msg;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inflate(data[, options]) -> Uint8Array|String
|
* inflate(data[, options]) -> Uint8Array|String
|
||||||
|
@ -375,18 +365,17 @@ Inflate.prototype.onEnd = function (status) {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
function inflate(input, options) {
|
export function inflate(input: Uint8Array, options: Partial<Options> = {}) {
|
||||||
const inflator = new Inflate(options);
|
const inflator = new Inflate(options);
|
||||||
|
|
||||||
inflator.push(input);
|
inflator.push(input, true);
|
||||||
|
|
||||||
// That will never happens, if you don't cheat with options :)
|
// That will never happens, if you don't cheat with options :)
|
||||||
if (inflator.err) throw inflator.msg || msg[inflator.err];
|
if (inflator.err) error(inflator.msg || messages[inflator.err]);
|
||||||
|
|
||||||
return inflator.result;
|
return inflator.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inflateRaw(data[, options]) -> Uint8Array|String
|
* inflateRaw(data[, options]) -> Uint8Array|String
|
||||||
* - data (Uint8Array|ArrayBuffer): input data to decompress.
|
* - data (Uint8Array|ArrayBuffer): input data to decompress.
|
||||||
|
@ -395,25 +384,10 @@ function inflate(input, options) {
|
||||||
* The same as [[inflate]], but creates raw data, without wrapper
|
* The same as [[inflate]], but creates raw data, without wrapper
|
||||||
* (header and adler32 crc).
|
* (header and adler32 crc).
|
||||||
**/
|
**/
|
||||||
function inflateRaw(input, options) {
|
export function inflateRaw(input: Uint8Array, options: Exclude<Partial<Options>, "raw"> = {}) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.raw = true;
|
options.raw = true;
|
||||||
return inflate(input, options);
|
return inflate(input, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * from "./zlib/constants";
|
||||||
/**
|
|
||||||
* ungzip(data[, options]) -> Uint8Array|String
|
|
||||||
* - data (Uint8Array|ArrayBuffer): input data to decompress.
|
|
||||||
* - options (Object): zlib inflate options.
|
|
||||||
*
|
|
||||||
* Just shortcut to [[inflate]], because it autodetects format
|
|
||||||
* by header.content. Done for convenience.
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.Inflate = Inflate;
|
|
||||||
module.exports.inflate = inflate;
|
|
||||||
module.exports.inflateRaw = inflateRaw;
|
|
||||||
module.exports.ungzip = inflate;
|
|
||||||
module.exports.constants = require('./zlib/constants');
|
|
||||||
|
|
137
src/utils/buffs.ts
Normal file
137
src/utils/buffs.ts
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
type StaticMembers<D> = {
|
||||||
|
length: number;
|
||||||
|
buf: buffer;
|
||||||
|
set(this: TypedArray<D>, array: TypedArray<D>, offset?: number): void;
|
||||||
|
subarray(this: TypedArray<D>, start: number, end?: number): TypedArray<D>;
|
||||||
|
zeroize(this: TypedArray<D>): void;
|
||||||
|
_startOffset?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TypedArray<D> = {
|
||||||
|
[index: number]: number;
|
||||||
|
} & StaticMembers<D> & {
|
||||||
|
__nominal_TypedArray: D;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TypedArrayConstructor<D> {
|
||||||
|
new (len: number): TypedArray<D>;
|
||||||
|
new (nums: number[]): TypedArray<D>;
|
||||||
|
from(buf: buffer): TypedArray<D>;
|
||||||
|
BYTES_PER_ELEMENT: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const makeTypedArray = <D extends number>({
|
||||||
|
bytesPerElement,
|
||||||
|
read,
|
||||||
|
write,
|
||||||
|
}: {
|
||||||
|
bytesPerElement: 1 | 2 | 4;
|
||||||
|
read: (buf: buffer, offset: number) => number;
|
||||||
|
write: (buf: buffer, offset: number, value: number) => void;
|
||||||
|
}) => {
|
||||||
|
const metatable: LuaMetatable<StaticMembers<D>> = {
|
||||||
|
__index: (me, index) => {
|
||||||
|
assert(typeIs(index, "number"), "index must be a number");
|
||||||
|
read(me.buf, index * bytesPerElement);
|
||||||
|
},
|
||||||
|
|
||||||
|
__newindex: (me, index, value) => {
|
||||||
|
assert(typeIs(index, "number"), "index must be a number");
|
||||||
|
assert(typeIs(value, "number"), "value must be a number");
|
||||||
|
write(me.buf, index * bytesPerElement, value);
|
||||||
|
},
|
||||||
|
|
||||||
|
__tostring: (me) => {
|
||||||
|
return buffer.tostring(me.buf);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function _make(buf: buffer): TypedArray<D> {
|
||||||
|
return setmetatable(
|
||||||
|
{
|
||||||
|
buf,
|
||||||
|
length: buffer.len(buf) / bytesPerElement,
|
||||||
|
|
||||||
|
set(this: TypedArray<D>, array: TypedArray<D>, offset = 0) {
|
||||||
|
buffer.copy(this.buf, offset * bytesPerElement, array.buf);
|
||||||
|
},
|
||||||
|
|
||||||
|
subarray(this: TypedArray<D>, start: number, finish: number = this.length) {
|
||||||
|
const len = finish - start;
|
||||||
|
const newBuf = buffer.create(len * bytesPerElement);
|
||||||
|
buffer.copy(newBuf, 0, this.buf, start * bytesPerElement, len);
|
||||||
|
return _make(newBuf);
|
||||||
|
},
|
||||||
|
|
||||||
|
zeroize(this: TypedArray<D>) {
|
||||||
|
buffer.fill(this.buf, 0, 0);
|
||||||
|
},
|
||||||
|
} satisfies StaticMembers<D>,
|
||||||
|
metatable,
|
||||||
|
) as unknown as TypedArray<D>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return class TypedArray {
|
||||||
|
constructor(nums: number | number[]) {
|
||||||
|
if (typeIs(nums, "number")) {
|
||||||
|
return _make(buffer.create(nums * bytesPerElement));
|
||||||
|
}
|
||||||
|
|
||||||
|
const buf = buffer.create(nums.size() * bytesPerElement);
|
||||||
|
let offset = 0;
|
||||||
|
for (const n of nums) {
|
||||||
|
write(buf, offset, n);
|
||||||
|
offset += bytesPerElement;
|
||||||
|
}
|
||||||
|
return _make(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static from(buf: buffer) {
|
||||||
|
return _make(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BYTES_PER_ELEMENT = bytesPerElement;
|
||||||
|
} as unknown as TypedArrayConstructor<D>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Uint8Array = makeTypedArray<-1>({
|
||||||
|
bytesPerElement: 1,
|
||||||
|
read: buffer.readu8,
|
||||||
|
write: buffer.writeu8,
|
||||||
|
});
|
||||||
|
export type Uint8Array = InstanceType<typeof Uint8Array>;
|
||||||
|
export const Uint16Array = makeTypedArray<-2>({
|
||||||
|
bytesPerElement: 2,
|
||||||
|
read: buffer.readu16,
|
||||||
|
write: buffer.writeu16,
|
||||||
|
});
|
||||||
|
export type Uint16Array = InstanceType<typeof Uint16Array>;
|
||||||
|
export const Uint32Array = makeTypedArray<-4>({
|
||||||
|
bytesPerElement: 4,
|
||||||
|
read: buffer.readu32,
|
||||||
|
write: buffer.writeu32,
|
||||||
|
});
|
||||||
|
export type Uint32Array = InstanceType<typeof Uint32Array>;
|
||||||
|
|
||||||
|
export const Int8Array = makeTypedArray<1>({
|
||||||
|
bytesPerElement: 1,
|
||||||
|
read: buffer.readi8,
|
||||||
|
write: buffer.writei8,
|
||||||
|
});
|
||||||
|
export type Int8Array = InstanceType<typeof Int8Array>;
|
||||||
|
export const Int16Array = makeTypedArray<2>({
|
||||||
|
bytesPerElement: 2,
|
||||||
|
read: buffer.readi16,
|
||||||
|
write: buffer.writei16,
|
||||||
|
});
|
||||||
|
export type Int16Array = InstanceType<typeof Int16Array>;
|
||||||
|
export const Int32Array = makeTypedArray<4>({
|
||||||
|
bytesPerElement: 4,
|
||||||
|
read: buffer.readi32,
|
||||||
|
write: buffer.writei32,
|
||||||
|
});
|
||||||
|
export type Int32Array = InstanceType<typeof Int32Array>;
|
||||||
|
|
||||||
|
export type NumericArrayLike = {
|
||||||
|
[index: number]: number;
|
||||||
|
};
|
|
@ -1,48 +1,29 @@
|
||||||
'use strict';
|
export function assign<T extends Record<keyof any, any>>(obj: T, ...sources: Partial<T>[]): T {
|
||||||
|
for (const source of sources) {
|
||||||
|
if (!typeIs(source, "table")) {
|
||||||
const _has = (obj, key) => {
|
error(source + "must be non-object");
|
||||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.assign = function (obj /*from1, from2, from3, ...*/) {
|
|
||||||
const sources = Array.prototype.slice.call(arguments, 1);
|
|
||||||
while (sources.length) {
|
|
||||||
const source = sources.shift();
|
|
||||||
if (!source) { continue; }
|
|
||||||
|
|
||||||
if (typeof source !== 'object') {
|
|
||||||
throw new TypeError(source + 'must be non-object');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const p in source) {
|
for (const [k, v] of pairs(source)) {
|
||||||
if (_has(source, p)) {
|
obj[k as keyof typeof obj] = v as T[keyof T];
|
||||||
obj[p] = source[p];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Join array of chunks to single array.
|
|
||||||
module.exports.flattenChunks = (chunks) => {
|
|
||||||
// calculate data length
|
|
||||||
let len = 0;
|
|
||||||
|
|
||||||
for (let i = 0, l = chunks.length; i < l; i++) {
|
|
||||||
len += chunks[i].length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// join chunks
|
export function flattenChunks(chunks: buffer[]): buffer {
|
||||||
const result = new Uint8Array(len);
|
// calculate data length
|
||||||
|
const len = chunks.reduce((acc, chunk) => acc + buffer.len(chunk), 0);
|
||||||
|
|
||||||
for (let i = 0, pos = 0, l = chunks.length; i < l; i++) {
|
// join chunks
|
||||||
let chunk = chunks[i];
|
const result = buffer.create(len);
|
||||||
result.set(chunk, pos);
|
let offset = 0;
|
||||||
pos += chunk.length;
|
|
||||||
|
for (const chunk of chunks) {
|
||||||
|
buffer.copy(result, offset, chunk);
|
||||||
|
offset += buffer.len(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,174 +0,0 @@
|
||||||
// String encode/decode helpers
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
// Quick check if we can use fast array to bin string conversion
|
|
||||||
//
|
|
||||||
// - apply(Array) can fail on Android 2.2
|
|
||||||
// - apply(Uint8Array) can fail on iOS 5.1 Safari
|
|
||||||
//
|
|
||||||
let STR_APPLY_UIA_OK = true;
|
|
||||||
|
|
||||||
try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }
|
|
||||||
|
|
||||||
|
|
||||||
// Table with utf8 lengths (calculated by first byte of sequence)
|
|
||||||
// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
|
|
||||||
// because max possible codepoint is 0x10ffff
|
|
||||||
const _utf8len = new Uint8Array(256);
|
|
||||||
for (let q = 0; q < 256; q++) {
|
|
||||||
_utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);
|
|
||||||
}
|
|
||||||
_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
|
|
||||||
|
|
||||||
|
|
||||||
// convert string to array (typed, when possible)
|
|
||||||
module.exports.string2buf = (str) => {
|
|
||||||
if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) {
|
|
||||||
return new TextEncoder().encode(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
|
|
||||||
|
|
||||||
// count binary size
|
|
||||||
for (m_pos = 0; m_pos < str_len; m_pos++) {
|
|
||||||
c = str.charCodeAt(m_pos);
|
|
||||||
if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
|
|
||||||
c2 = str.charCodeAt(m_pos + 1);
|
|
||||||
if ((c2 & 0xfc00) === 0xdc00) {
|
|
||||||
c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
|
|
||||||
m_pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate buffer
|
|
||||||
buf = new Uint8Array(buf_len);
|
|
||||||
|
|
||||||
// convert
|
|
||||||
for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
|
|
||||||
c = str.charCodeAt(m_pos);
|
|
||||||
if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {
|
|
||||||
c2 = str.charCodeAt(m_pos + 1);
|
|
||||||
if ((c2 & 0xfc00) === 0xdc00) {
|
|
||||||
c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
|
|
||||||
m_pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c < 0x80) {
|
|
||||||
/* one byte */
|
|
||||||
buf[i++] = c;
|
|
||||||
} else if (c < 0x800) {
|
|
||||||
/* two bytes */
|
|
||||||
buf[i++] = 0xC0 | (c >>> 6);
|
|
||||||
buf[i++] = 0x80 | (c & 0x3f);
|
|
||||||
} else if (c < 0x10000) {
|
|
||||||
/* three bytes */
|
|
||||||
buf[i++] = 0xE0 | (c >>> 12);
|
|
||||||
buf[i++] = 0x80 | (c >>> 6 & 0x3f);
|
|
||||||
buf[i++] = 0x80 | (c & 0x3f);
|
|
||||||
} else {
|
|
||||||
/* four bytes */
|
|
||||||
buf[i++] = 0xf0 | (c >>> 18);
|
|
||||||
buf[i++] = 0x80 | (c >>> 12 & 0x3f);
|
|
||||||
buf[i++] = 0x80 | (c >>> 6 & 0x3f);
|
|
||||||
buf[i++] = 0x80 | (c & 0x3f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper
|
|
||||||
const buf2binstring = (buf, len) => {
|
|
||||||
// On Chrome, the arguments in a function call that are allowed is `65534`.
|
|
||||||
// If the length of the buffer is smaller than that, we can use this optimization,
|
|
||||||
// otherwise we will take a slower path.
|
|
||||||
if (len < 65534) {
|
|
||||||
if (buf.subarray && STR_APPLY_UIA_OK) {
|
|
||||||
return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = '';
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
result += String.fromCharCode(buf[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// convert array to string
|
|
||||||
module.exports.buf2string = (buf, max) => {
|
|
||||||
const len = max || buf.length;
|
|
||||||
|
|
||||||
if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) {
|
|
||||||
return new TextDecoder().decode(buf.subarray(0, max));
|
|
||||||
}
|
|
||||||
|
|
||||||
let i, out;
|
|
||||||
|
|
||||||
// Reserve max possible length (2 words per char)
|
|
||||||
// NB: by unknown reasons, Array is significantly faster for
|
|
||||||
// String.fromCharCode.apply than Uint16Array.
|
|
||||||
const utf16buf = new Array(len * 2);
|
|
||||||
|
|
||||||
for (out = 0, i = 0; i < len;) {
|
|
||||||
let c = buf[i++];
|
|
||||||
// quick process ascii
|
|
||||||
if (c < 0x80) { utf16buf[out++] = c; continue; }
|
|
||||||
|
|
||||||
let c_len = _utf8len[c];
|
|
||||||
// skip 5 & 6 byte codes
|
|
||||||
if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }
|
|
||||||
|
|
||||||
// apply mask on first byte
|
|
||||||
c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
|
|
||||||
// join the rest
|
|
||||||
while (c_len > 1 && i < len) {
|
|
||||||
c = (c << 6) | (buf[i++] & 0x3f);
|
|
||||||
c_len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// terminated by end of string?
|
|
||||||
if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
|
|
||||||
|
|
||||||
if (c < 0x10000) {
|
|
||||||
utf16buf[out++] = c;
|
|
||||||
} else {
|
|
||||||
c -= 0x10000;
|
|
||||||
utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
|
|
||||||
utf16buf[out++] = 0xdc00 | (c & 0x3ff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf2binstring(utf16buf, out);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate max possible position in utf8 buffer,
|
|
||||||
// that will not break sequence. If that's not possible
|
|
||||||
// - (very small limits) return max size as is.
|
|
||||||
//
|
|
||||||
// buf[] - utf8 bytes array
|
|
||||||
// max - length limit (mandatory);
|
|
||||||
module.exports.utf8border = (buf, max) => {
|
|
||||||
|
|
||||||
max = max || buf.length;
|
|
||||||
if (max > buf.length) { max = buf.length; }
|
|
||||||
|
|
||||||
// go back from last position, until start of sequence found
|
|
||||||
let pos = max - 1;
|
|
||||||
while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
|
|
||||||
|
|
||||||
// Very small and broken sequence,
|
|
||||||
// return max, because we should return something anyway.
|
|
||||||
if (pos < 0) { return max; }
|
|
||||||
|
|
||||||
// If we came to start of buffer - that means buffer is too small,
|
|
||||||
// return max too.
|
|
||||||
if (pos === 0) { return max; }
|
|
||||||
|
|
||||||
return (pos + _utf8len[buf[pos]] > max) ? pos : max;
|
|
||||||
};
|
|
|
@ -1,4 +1,6 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { NumericArrayLike } from "../utils/buffs";
|
||||||
|
|
||||||
// Note: adler32 takes 12% for level 0 and 2% for level 6.
|
// Note: adler32 takes 12% for level 0 and 2% for level 6.
|
||||||
// It isn't worth it to make additional optimizations as in original.
|
// It isn't worth it to make additional optimizations as in original.
|
||||||
|
@ -23,7 +25,7 @@
|
||||||
// misrepresented as being the original software.
|
// misrepresented as being the original software.
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
const adler32 = (adler, buf, len, pos) => {
|
export const adler32 = (adler: number, buf: NumericArrayLike, len: number, pos: number) => {
|
||||||
let s1 = (adler & 0xffff) | 0,
|
let s1 = (adler & 0xffff) | 0,
|
||||||
s2 = ((adler >>> 16) & 0xffff) | 0,
|
s2 = ((adler >>> 16) & 0xffff) | 0,
|
||||||
n = 0;
|
n = 0;
|
||||||
|
@ -44,8 +46,5 @@ const adler32 = (adler, buf, len, pos) => {
|
||||||
s2 %= 65521;
|
s2 %= 65521;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (s1 | (s2 << 16)) |0;
|
return s1 | (s2 << 16) | 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = adler32;
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -19,50 +19,46 @@
|
||||||
// misrepresented as being the original software.
|
// misrepresented as being the original software.
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
|
|
||||||
/* Allowed flush values; see deflate() and inflate() below for details */
|
/* Allowed flush values; see deflate() and inflate() below for details */
|
||||||
Z_NO_FLUSH: 0,
|
export const Z_NO_FLUSH = 0;
|
||||||
Z_PARTIAL_FLUSH: 1,
|
export const Z_PARTIAL_FLUSH = 1;
|
||||||
Z_SYNC_FLUSH: 2,
|
export const Z_SYNC_FLUSH = 2;
|
||||||
Z_FULL_FLUSH: 3,
|
export const Z_FULL_FLUSH = 3;
|
||||||
Z_FINISH: 4,
|
export const Z_FINISH = 4;
|
||||||
Z_BLOCK: 5,
|
export const Z_BLOCK = 5;
|
||||||
Z_TREES: 6,
|
export const Z_TREES = 6;
|
||||||
|
|
||||||
/* Return codes for the compression/decompression functions. Negative values
|
/* Return codes for the compression/decompression functions. Negative values
|
||||||
* are errors, positive values are used for special but normal events.
|
* are errors, positive values are used for special but normal events.
|
||||||
*/
|
*/
|
||||||
Z_OK: 0,
|
export const Z_OK = 0;
|
||||||
Z_STREAM_END: 1,
|
export const Z_STREAM_END = 1;
|
||||||
Z_NEED_DICT: 2,
|
export const Z_NEED_DICT = 2;
|
||||||
Z_ERRNO: -1,
|
export const Z_ERRNO = -1;
|
||||||
Z_STREAM_ERROR: -2,
|
export const Z_STREAM_ERROR = -2;
|
||||||
Z_DATA_ERROR: -3,
|
export const Z_DATA_ERROR = -3;
|
||||||
Z_MEM_ERROR: -4,
|
export const Z_MEM_ERROR = -4;
|
||||||
Z_BUF_ERROR: -5,
|
export const Z_BUF_ERROR = -5;
|
||||||
//Z_VERSION_ERROR: -6,
|
//Z_VERSION_ERROR: -6,
|
||||||
|
|
||||||
/* compression levels */
|
/* compression levels */
|
||||||
Z_NO_COMPRESSION: 0,
|
export const Z_NO_COMPRESSION = 0;
|
||||||
Z_BEST_SPEED: 1,
|
export const Z_BEST_SPEED = 1;
|
||||||
Z_BEST_COMPRESSION: 9,
|
export const Z_BEST_COMPRESSION = 9;
|
||||||
Z_DEFAULT_COMPRESSION: -1,
|
export const Z_DEFAULT_COMPRESSION = -1;
|
||||||
|
|
||||||
|
export const Z_FILTERED = 1;
|
||||||
Z_FILTERED: 1,
|
export const Z_HUFFMAN_ONLY = 2;
|
||||||
Z_HUFFMAN_ONLY: 2,
|
export const Z_RLE = 3;
|
||||||
Z_RLE: 3,
|
export const Z_FIXED = 4;
|
||||||
Z_FIXED: 4,
|
export const Z_DEFAULT_STRATEGY = 0;
|
||||||
Z_DEFAULT_STRATEGY: 0,
|
|
||||||
|
|
||||||
/* Possible values of the data_type field (though see inflate()) */
|
/* Possible values of the data_type field (though see inflate()) */
|
||||||
Z_BINARY: 0,
|
export const Z_BINARY = 0;
|
||||||
Z_TEXT: 1,
|
export const Z_TEXT = 1;
|
||||||
//Z_ASCII: 1, // = Z_TEXT (deprecated)
|
//Z_ASCII: 1, // = Z_TEXT (deprecated)
|
||||||
Z_UNKNOWN: 2,
|
export const Z_UNKNOWN = 2;
|
||||||
|
|
||||||
/* The deflate compression method */
|
/* The deflate compression method */
|
||||||
Z_DEFLATED: 8
|
export const Z_DEFLATED = 8;
|
||||||
//Z_NULL: null // Use -1 or null inline, depending on var type
|
//Z_NULL: null // Use -1 or null inline, depending on var type
|
||||||
};
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { NumericArrayLike, Uint32Array } from "../utils/buffs";
|
||||||
|
|
||||||
// Note: we can't get significant speed boost here.
|
// Note: we can't get significant speed boost here.
|
||||||
// So write code to minimize size - no pregenerated tables
|
// So write code to minimize size - no pregenerated tables
|
||||||
|
@ -25,35 +27,31 @@
|
||||||
|
|
||||||
// Use ordinary array, since untyped makes no boost here
|
// Use ordinary array, since untyped makes no boost here
|
||||||
const makeTable = () => {
|
const makeTable = () => {
|
||||||
let c, table = [];
|
let c;
|
||||||
|
const tbl = [];
|
||||||
|
|
||||||
for (var n = 0; n < 256; n++) {
|
for (let n = 0; n < 256; n++) {
|
||||||
c = n;
|
c = n;
|
||||||
for (var k = 0; k < 8; k++) {
|
for (let k = 0; k < 8; k++) {
|
||||||
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
|
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
||||||
}
|
}
|
||||||
table[n] = c;
|
tbl[n] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
return table;
|
return tbl;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create table on load. Just 255 signed longs. Not a problem.
|
// Create table on load. Just 255 signed longs. Not a problem.
|
||||||
const crcTable = new Uint32Array(makeTable());
|
const crcTable = new Uint32Array(makeTable());
|
||||||
|
|
||||||
|
export function crc32(crc: number, buf: NumericArrayLike, len: number, pos: number) {
|
||||||
const crc32 = (crc, buf, len, pos) => {
|
const finish = pos + len;
|
||||||
const t = crcTable;
|
|
||||||
const end = pos + len;
|
|
||||||
|
|
||||||
crc ^= -1;
|
crc ^= -1;
|
||||||
|
|
||||||
for (let i = pos; i < end; i++) {
|
for (let i = pos; i < finish; i++) {
|
||||||
crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
|
crc = (crc >>> 8) ^ crcTable[(crc ^ buf[i]) & 0xff];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (crc ^ (-1)); // >>> 0;
|
return crc ^ -1; // >>> 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = crc32;
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,6 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { Uint8Array } from "../utils/buffs";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -19,19 +21,19 @@
|
||||||
// misrepresented as being the original software.
|
// misrepresented as being the original software.
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
function GZheader() {
|
export class GZheader {
|
||||||
/* true if compressed data believed to be text */
|
/* true if compressed data believed to be text */
|
||||||
this.text = 0;
|
public text = 0;
|
||||||
/* modification time */
|
/* modification time */
|
||||||
this.time = 0;
|
public time = 0;
|
||||||
/* extra flags (not used when writing a gzip file) */
|
/* extra flags (not used when writing a gzip file) */
|
||||||
this.xflags = 0;
|
public xflags = 0;
|
||||||
/* operating system */
|
/* operating system */
|
||||||
this.os = 0;
|
public os = 0;
|
||||||
/* pointer to extra field or Z_NULL if none */
|
/* pointer to extra field or Z_NULL if none */
|
||||||
this.extra = null;
|
public extra?: Uint8Array;
|
||||||
/* extra field length (valid if extra != Z_NULL) */
|
/* extra field length (valid if extra != Z_NULL) */
|
||||||
this.extra_len = 0; // Actually, we don't need it in JS,
|
public extra_len = 0; // Actually, we don't need it in JS,
|
||||||
// but leave for few code modifications
|
// but leave for few code modifications
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -40,19 +42,17 @@ function GZheader() {
|
||||||
//
|
//
|
||||||
|
|
||||||
/* space at extra (only when reading header) */
|
/* space at extra (only when reading header) */
|
||||||
// this.extra_max = 0;
|
// public extra_max = 0;
|
||||||
/* pointer to zero-terminated file name or Z_NULL */
|
/* pointer to zero-terminated file name or Z_NULL */
|
||||||
this.name = '';
|
public name = "";
|
||||||
/* space at name (only when reading header) */
|
/* space at name (only when reading header) */
|
||||||
// this.name_max = 0;
|
// public name_max = 0;
|
||||||
/* pointer to zero-terminated comment or Z_NULL */
|
/* pointer to zero-terminated comment or Z_NULL */
|
||||||
this.comment = '';
|
public comment = "";
|
||||||
/* space at comment (only when reading header) */
|
/* space at comment (only when reading header) */
|
||||||
// this.comm_max = 0;
|
// public comm_max = 0;
|
||||||
/* true if there was or will be a header crc */
|
/* true if there was or will be a header crc */
|
||||||
this.hcrc = 0;
|
public hcrc = 0;
|
||||||
/* true when done reading gzip header (not used when writing a gzip file) */
|
/* true when done reading gzip header (not used when writing a gzip file) */
|
||||||
this.done = false;
|
public done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = GZheader;
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { InflateState } from "./inflate";
|
||||||
|
import { ZStream } from "./zstream";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -58,12 +61,12 @@ const TYPE = 16191; /* i: waiting for type bits, including last-flag bit */
|
||||||
requires strm.avail_out >= 258 for each loop to avoid checking for
|
requires strm.avail_out >= 258 for each loop to avoid checking for
|
||||||
output space.
|
output space.
|
||||||
*/
|
*/
|
||||||
module.exports = function inflate_fast(strm, start) {
|
export function inflate_fast(strm: ZStream<InflateState>, start: number) {
|
||||||
let _in; /* local strm.input */
|
let _in; /* local strm.input */
|
||||||
let last; /* have enough input while in < last */
|
let last; /* have enough input while in < last */
|
||||||
let _out; /* local strm.output */
|
let _out; /* local strm.output */
|
||||||
let beg; /* inflate()'s initial strm.output */
|
let beg; /* inflate()'s initial strm.output */
|
||||||
let end; /* while out < end, enough space available */
|
let finish; /* while out < end, enough space available */
|
||||||
//#ifdef INFLATE_STRICT
|
//#ifdef INFLATE_STRICT
|
||||||
let dmax; /* maximum distance from zlib header */
|
let dmax; /* maximum distance from zlib header */
|
||||||
//#endif
|
//#endif
|
||||||
|
@ -86,7 +89,6 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
let from; /* where to copy match from */
|
let from; /* where to copy match from */
|
||||||
let from_source;
|
let from_source;
|
||||||
|
|
||||||
|
|
||||||
let input, output; // JS specific, because we have no pointers
|
let input, output; // JS specific, because we have no pointers
|
||||||
|
|
||||||
/* copy state to local variables */
|
/* copy state to local variables */
|
||||||
|
@ -98,7 +100,7 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
_out = strm.next_out;
|
_out = strm.next_out;
|
||||||
output = strm.output;
|
output = strm.output;
|
||||||
beg = _out - (start - strm.avail_out);
|
beg = _out - (start - strm.avail_out);
|
||||||
end = _out + (strm.avail_out - 257);
|
finish = _out + (strm.avail_out - 257);
|
||||||
//#ifdef INFLATE_STRICT
|
//#ifdef INFLATE_STRICT
|
||||||
dmax = state.dmax;
|
dmax = state.dmax;
|
||||||
//#endif
|
//#endif
|
||||||
|
@ -113,12 +115,16 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
lmask = (1 << state.lenbits) - 1;
|
lmask = (1 << state.lenbits) - 1;
|
||||||
dmask = (1 << state.distbits) - 1;
|
dmask = (1 << state.distbits) - 1;
|
||||||
|
|
||||||
|
|
||||||
/* decode literals and length/distances until end-of-block or not enough
|
/* decode literals and length/distances until end-of-block or not enough
|
||||||
input data or output space */
|
input data or output space */
|
||||||
|
|
||||||
top:
|
let break_top = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (break_top) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (bits < 15) {
|
if (bits < 15) {
|
||||||
hold += input[_in++] << bits;
|
hold += input[_in++] << bits;
|
||||||
bits += 8;
|
bits += 8;
|
||||||
|
@ -128,19 +134,24 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
|
|
||||||
here = lcode[hold & lmask];
|
here = lcode[hold & lmask];
|
||||||
|
|
||||||
dolen:
|
for (;;) {
|
||||||
for (;;) { // Goto emulation
|
if (break_top) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Goto emulation
|
||||||
op = here >>> 24 /*here.bits*/;
|
op = here >>> 24 /*here.bits*/;
|
||||||
hold >>>= op;
|
hold >>>= op;
|
||||||
bits -= op;
|
bits -= op;
|
||||||
op = (here >>> 16) & 0xff /*here.op*/;
|
op = (here >>> 16) & 0xff /*here.op*/;
|
||||||
if (op === 0) { /* literal */
|
if (op === 0) {
|
||||||
|
/* literal */
|
||||||
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||||
// "inflate: literal '%c'\n" :
|
// "inflate: literal '%c'\n" :
|
||||||
// "inflate: literal 0x%02x\n", here.val));
|
// "inflate: literal 0x%02x\n", here.val));
|
||||||
output[_out++] = here & 0xffff /*here.val*/;
|
output[_out++] = here & 0xffff /*here.val*/;
|
||||||
}
|
} else if (op & 16) {
|
||||||
else if (op & 16) { /* length base */
|
/* length base */
|
||||||
len = here & 0xffff /*here.val*/;
|
len = here & 0xffff /*here.val*/;
|
||||||
op &= 15; /* number of extra bits */
|
op &= 15; /* number of extra bits */
|
||||||
if (op) {
|
if (op) {
|
||||||
|
@ -161,14 +172,15 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
}
|
}
|
||||||
here = dcode[hold & dmask];
|
here = dcode[hold & dmask];
|
||||||
|
|
||||||
dodist:
|
for (;;) {
|
||||||
for (;;) { // goto emulation
|
// goto emulation
|
||||||
op = here >>> 24 /*here.bits*/;
|
op = here >>> 24 /*here.bits*/;
|
||||||
hold >>>= op;
|
hold >>>= op;
|
||||||
bits -= op;
|
bits -= op;
|
||||||
op = (here >>> 16) & 0xff /*here.op*/;
|
op = (here >>> 16) & 0xff /*here.op*/;
|
||||||
|
|
||||||
if (op & 16) { /* distance base */
|
if (op & 16) {
|
||||||
|
/* distance base */
|
||||||
dist = here & 0xffff /*here.val*/;
|
dist = here & 0xffff /*here.val*/;
|
||||||
op &= 15; /* number of extra bits */
|
op &= 15; /* number of extra bits */
|
||||||
if (bits < op) {
|
if (bits < op) {
|
||||||
|
@ -182,22 +194,25 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
dist += hold & ((1 << op) - 1);
|
dist += hold & ((1 << op) - 1);
|
||||||
//#ifdef INFLATE_STRICT
|
//#ifdef INFLATE_STRICT
|
||||||
if (dist > dmax) {
|
if (dist > dmax) {
|
||||||
strm.msg = 'invalid distance too far back';
|
strm.msg = "invalid distance too far back";
|
||||||
state.mode = BAD;
|
state.mode = BAD;
|
||||||
break top;
|
break_top = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
hold >>>= op;
|
hold >>>= op;
|
||||||
bits -= op;
|
bits -= op;
|
||||||
//Tracevv((stderr, "inflate: distance %u\n", dist));
|
//Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||||
op = _out - beg; /* max distance in output */
|
op = _out - beg; /* max distance in output */
|
||||||
if (dist > op) { /* see if copy from window */
|
if (dist > op) {
|
||||||
|
/* see if copy from window */
|
||||||
op = dist - op; /* distance back in window */
|
op = dist - op; /* distance back in window */
|
||||||
if (op > whave) {
|
if (op > whave) {
|
||||||
if (state.sane) {
|
if (state.sane) {
|
||||||
strm.msg = 'invalid distance too far back';
|
strm.msg = "invalid distance too far back";
|
||||||
state.mode = BAD;
|
state.mode = BAD;
|
||||||
break top;
|
break_top = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (!) This block is disabled in zlib defaults,
|
// (!) This block is disabled in zlib defaults,
|
||||||
|
@ -224,9 +239,11 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
}
|
}
|
||||||
from = 0; // window index
|
from = 0; // window index
|
||||||
from_source = s_window;
|
from_source = s_window;
|
||||||
if (wnext === 0) { /* very common case */
|
if (wnext === 0) {
|
||||||
|
/* very common case */
|
||||||
from += wsize - op;
|
from += wsize - op;
|
||||||
if (op < len) { /* some from window */
|
if (op < len) {
|
||||||
|
/* some from window */
|
||||||
len -= op;
|
len -= op;
|
||||||
do {
|
do {
|
||||||
output[_out++] = s_window[from++];
|
output[_out++] = s_window[from++];
|
||||||
|
@ -234,17 +251,19 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
from = _out - dist; /* rest from output */
|
from = _out - dist; /* rest from output */
|
||||||
from_source = output;
|
from_source = output;
|
||||||
}
|
}
|
||||||
}
|
} else if (wnext < op) {
|
||||||
else if (wnext < op) { /* wrap around window */
|
/* wrap around window */
|
||||||
from += wsize + wnext - op;
|
from += wsize + wnext - op;
|
||||||
op -= wnext;
|
op -= wnext;
|
||||||
if (op < len) { /* some from end of window */
|
if (op < len) {
|
||||||
|
/* some from end of window */
|
||||||
len -= op;
|
len -= op;
|
||||||
do {
|
do {
|
||||||
output[_out++] = s_window[from++];
|
output[_out++] = s_window[from++];
|
||||||
} while (--op);
|
} while (--op);
|
||||||
from = 0;
|
from = 0;
|
||||||
if (wnext < len) { /* some from start of window */
|
if (wnext < len) {
|
||||||
|
/* some from start of window */
|
||||||
op = wnext;
|
op = wnext;
|
||||||
len -= op;
|
len -= op;
|
||||||
do {
|
do {
|
||||||
|
@ -254,10 +273,11 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
from_source = output;
|
from_source = output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else { /* contiguous in window */
|
/* contiguous in window */
|
||||||
from += wnext - op;
|
from += wnext - op;
|
||||||
if (op < len) { /* some from window */
|
if (op < len) {
|
||||||
|
/* some from window */
|
||||||
len -= op;
|
len -= op;
|
||||||
do {
|
do {
|
||||||
output[_out++] = s_window[from++];
|
output[_out++] = s_window[from++];
|
||||||
|
@ -278,10 +298,10 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
output[_out++] = from_source[from++];
|
output[_out++] = from_source[from++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
from = _out - dist; /* copy direct from output */
|
from = _out - dist; /* copy direct from output */
|
||||||
do { /* minimum length is three */
|
do {
|
||||||
|
/* minimum length is three */
|
||||||
output[_out++] = output[from++];
|
output[_out++] = output[from++];
|
||||||
output[_out++] = output[from++];
|
output[_out++] = output[from++];
|
||||||
output[_out++] = output[from++];
|
output[_out++] = output[from++];
|
||||||
|
@ -294,38 +314,36 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if ((op & 64) === 0) {
|
||||||
else if ((op & 64) === 0) { /* 2nd level distance code */
|
/* 2nd level distance code */
|
||||||
here = dcode[(here & 0xffff) /*here.val*/ + (hold & ((1 << op) - 1))];
|
here = dcode[(here & 0xffff) /*here.val*/ + (hold & ((1 << op) - 1))];
|
||||||
continue dodist;
|
continue;
|
||||||
}
|
} else {
|
||||||
else {
|
strm.msg = "invalid distance code";
|
||||||
strm.msg = 'invalid distance code';
|
|
||||||
state.mode = BAD;
|
state.mode = BAD;
|
||||||
break top;
|
break_top = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break; // need to emulate goto via "continue"
|
break; // need to emulate goto via "continue"
|
||||||
}
|
}
|
||||||
}
|
} else if ((op & 64) === 0) {
|
||||||
else if ((op & 64) === 0) { /* 2nd level length code */
|
/* 2nd level length code */
|
||||||
here = lcode[(here & 0xffff) /*here.val*/ + (hold & ((1 << op) - 1))];
|
here = lcode[(here & 0xffff) /*here.val*/ + (hold & ((1 << op) - 1))];
|
||||||
continue dolen;
|
continue;
|
||||||
}
|
} else if (op & 32) {
|
||||||
else if (op & 32) { /* end-of-block */
|
/* end-of-block */
|
||||||
//Tracevv((stderr, "inflate: end of block\n"));
|
//Tracevv((stderr, "inflate: end of block\n"));
|
||||||
state.mode = TYPE;
|
state.mode = TYPE;
|
||||||
break top;
|
break_top = true;
|
||||||
}
|
} else {
|
||||||
else {
|
strm.msg = "invalid literal/length code";
|
||||||
strm.msg = 'invalid literal/length code';
|
|
||||||
state.mode = BAD;
|
state.mode = BAD;
|
||||||
break top;
|
break_top = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break; // need to emulate goto via "continue"
|
break; // need to emulate goto via "continue"
|
||||||
}
|
}
|
||||||
} while (_in < last && _out < end);
|
} while (_in < last && _out < finish);
|
||||||
|
|
||||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||||
len = bits >> 3;
|
len = bits >> 3;
|
||||||
|
@ -336,9 +354,9 @@ module.exports = function inflate_fast(strm, start) {
|
||||||
/* update state and return */
|
/* update state and return */
|
||||||
strm.next_in = _in;
|
strm.next_in = _in;
|
||||||
strm.next_out = _out;
|
strm.next_out = _out;
|
||||||
strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
|
strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
|
||||||
strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
|
strm.avail_out = _out < finish ? 257 + (finish - _out) : 257 - (_out - finish);
|
||||||
state.hold = hold;
|
state.hold = hold;
|
||||||
state.bits = bits;
|
state.bits = bits;
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,6 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { NumericArrayLike, Uint16Array, Uint8Array } from "../utils/buffs";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -28,36 +30,43 @@ const CODES = 0;
|
||||||
const LENS = 1;
|
const LENS = 1;
|
||||||
const DISTS = 2;
|
const DISTS = 2;
|
||||||
|
|
||||||
const lbase = new Uint16Array([ /* Length codes 257..285 base */
|
const lbase = new Uint16Array([
|
||||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
/* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83,
|
||||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
|
99, 115, 131, 163, 195, 227, 258, 0, 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const lext = new Uint8Array([ /* Length codes 257..285 extra */
|
const lext = new Uint8Array([
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
/* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
|
||||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
|
20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const dbase = new Uint16Array([ /* Distance codes 0..29 base */
|
const dbase = new Uint16Array([
|
||||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
/* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025,
|
||||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0,
|
||||||
8193, 12289, 16385, 24577, 0, 0
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const dext = new Uint8Array([ /* Distance codes 0..29 extra */
|
const dext = new Uint8Array([
|
||||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
/* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25,
|
||||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64,
|
||||||
28, 28, 29, 29, 64, 64
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) =>
|
export const inflate_table = (
|
||||||
{
|
ty: number,
|
||||||
|
lens: NumericArrayLike,
|
||||||
|
lens_index: number,
|
||||||
|
codes: number,
|
||||||
|
tbl: NumericArrayLike,
|
||||||
|
table_index: number,
|
||||||
|
work: NumericArrayLike,
|
||||||
|
opts: { bits: number },
|
||||||
|
) => {
|
||||||
const bits = opts.bits;
|
const bits = opts.bits;
|
||||||
//here = opts.here; /* table entry for duplication */
|
//here = opts.here; /* table entry for duplication */
|
||||||
|
|
||||||
let len = 0; /* a code's length in bits */
|
let len = 0; /* a code's length in bits */
|
||||||
let sym = 0; /* index of code symbols */
|
let sym = 0; /* index of code symbols */
|
||||||
let min = 0, max = 0; /* minimum and maximum code lengths */
|
let min = 0,
|
||||||
|
max = 0; /* minimum and maximum code lengths */
|
||||||
let root = 0; /* number of index bits for root table */
|
let root = 0; /* number of index bits for root table */
|
||||||
let curr = 0; /* number of index bits for current table */
|
let curr = 0; /* number of index bits for current table */
|
||||||
let drop = 0; /* code bits to drop for sub-table */
|
let drop = 0; /* code bits to drop for sub-table */
|
||||||
|
@ -68,13 +77,13 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
let fill; /* index for replicating entries */
|
let fill; /* index for replicating entries */
|
||||||
let low; /* low bits for current root entry */
|
let low; /* low bits for current root entry */
|
||||||
let mask; /* mask for low root bits */
|
let mask; /* mask for low root bits */
|
||||||
let next; /* next available space in table */
|
let next_space; /* next available space in table */
|
||||||
let base = null; /* base value table to use */
|
let base; /* base value table to use */
|
||||||
// let shoextra; /* extra bits table to use */
|
// let shoextra; /* extra bits table to use */
|
||||||
let match; /* use base and extra for symbol >= match */
|
let match; /* use base and extra for symbol >= match */
|
||||||
const count = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
|
const count = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
|
||||||
const offs = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
|
const offs = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
|
||||||
let extra = null;
|
let extra;
|
||||||
|
|
||||||
let here_bits, here_op, here_val;
|
let here_bits, here_op, here_val;
|
||||||
|
|
||||||
|
@ -120,28 +129,32 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
/* bound code lengths, force root to be within code lengths */
|
/* bound code lengths, force root to be within code lengths */
|
||||||
root = bits;
|
root = bits;
|
||||||
for (max = MAXBITS; max >= 1; max--) {
|
for (max = MAXBITS; max >= 1; max--) {
|
||||||
if (count[max] !== 0) { break; }
|
if (count[max] !== 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (root > max) {
|
if (root > max) {
|
||||||
root = max;
|
root = max;
|
||||||
}
|
}
|
||||||
if (max === 0) { /* no symbols to code at all */
|
if (max === 0) {
|
||||||
|
/* no symbols to code at all */
|
||||||
//table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
|
//table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
|
||||||
//table.bits[opts.table_index] = 1; //here.bits = (var char)1;
|
//table.bits[opts.table_index] = 1; //here.bits = (var char)1;
|
||||||
//table.val[opts.table_index++] = 0; //here.val = (var short)0;
|
//table.val[opts.table_index++] = 0; //here.val = (var short)0;
|
||||||
table[table_index++] = (1 << 24) | (64 << 16) | 0;
|
tbl[table_index++] = (1 << 24) | (64 << 16) | 0;
|
||||||
|
|
||||||
|
|
||||||
//table.op[opts.table_index] = 64;
|
//table.op[opts.table_index] = 64;
|
||||||
//table.bits[opts.table_index] = 1;
|
//table.bits[opts.table_index] = 1;
|
||||||
//table.val[opts.table_index++] = 0;
|
//table.val[opts.table_index++] = 0;
|
||||||
table[table_index++] = (1 << 24) | (64 << 16) | 0;
|
tbl[table_index++] = (1 << 24) | (64 << 16) | 0;
|
||||||
|
|
||||||
opts.bits = 1;
|
opts.bits = 1;
|
||||||
return 0; /* no symbols, but wait for decoding to report error */
|
return 0; /* no symbols, but wait for decoding to report error */
|
||||||
}
|
}
|
||||||
for (min = 1; min < max; min++) {
|
for (min = 1; min < max; min++) {
|
||||||
if (count[min] !== 0) { break; }
|
if (count[min] !== 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (root < min) {
|
if (root < min) {
|
||||||
root = min;
|
root = min;
|
||||||
|
@ -156,7 +169,7 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
return -1;
|
return -1;
|
||||||
} /* over-subscribed */
|
} /* over-subscribed */
|
||||||
}
|
}
|
||||||
if (left > 0 && (type === CODES || max !== 1)) {
|
if (left > 0 && (ty === CODES || max !== 1)) {
|
||||||
return -1; /* incomplete set */
|
return -1; /* incomplete set */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,16 +220,15 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
/* set up for code type */
|
/* set up for code type */
|
||||||
// poor man optimization - use if-else instead of switch,
|
// poor man optimization - use if-else instead of switch,
|
||||||
// to avoid deopts in old v8
|
// to avoid deopts in old v8
|
||||||
if (type === CODES) {
|
if (ty === CODES) {
|
||||||
base = extra = work; /* dummy value--not used */
|
base = extra = work; /* dummy value--not used */
|
||||||
match = 20;
|
match = 20;
|
||||||
|
} else if (ty === LENS) {
|
||||||
} else if (type === LENS) {
|
|
||||||
base = lbase;
|
base = lbase;
|
||||||
extra = lext;
|
extra = lext;
|
||||||
match = 257;
|
match = 257;
|
||||||
|
} else {
|
||||||
} else { /* DISTS */
|
/* DISTS */
|
||||||
base = dbase;
|
base = dbase;
|
||||||
extra = dext;
|
extra = dext;
|
||||||
match = 0;
|
match = 0;
|
||||||
|
@ -226,7 +238,7 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
huff = 0; /* starting code */
|
huff = 0; /* starting code */
|
||||||
sym = 0; /* starting code symbol */
|
sym = 0; /* starting code symbol */
|
||||||
len = min; /* starting code length */
|
len = min; /* starting code length */
|
||||||
next = table_index; /* current table to fill in */
|
next_space = table_index; /* current table to fill in */
|
||||||
curr = root; /* current table index bits */
|
curr = root; /* current table index bits */
|
||||||
drop = 0; /* current bits to drop from code for index */
|
drop = 0; /* current bits to drop from code for index */
|
||||||
low = -1; /* trigger new sub-table when len > root */
|
low = -1; /* trigger new sub-table when len > root */
|
||||||
|
@ -234,8 +246,7 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
mask = used - 1; /* mask for comparing low */
|
mask = used - 1; /* mask for comparing low */
|
||||||
|
|
||||||
/* check available table space */
|
/* check available table space */
|
||||||
if ((type === LENS && used > ENOUGH_LENS) ||
|
if ((ty === LENS && used > ENOUGH_LENS) || (ty === DISTS && used > ENOUGH_DISTS)) {
|
||||||
(type === DISTS && used > ENOUGH_DISTS)) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,12 +257,10 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
if (work[sym] + 1 < match) {
|
if (work[sym] + 1 < match) {
|
||||||
here_op = 0;
|
here_op = 0;
|
||||||
here_val = work[sym];
|
here_val = work[sym];
|
||||||
}
|
} else if (work[sym] >= match) {
|
||||||
else if (work[sym] >= match) {
|
|
||||||
here_op = extra[work[sym] - match];
|
here_op = extra[work[sym] - match];
|
||||||
here_val = base[work[sym] - match];
|
here_val = base[work[sym] - match];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
here_op = 32 + 64; /* end of block */
|
here_op = 32 + 64; /* end of block */
|
||||||
here_val = 0;
|
here_val = 0;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +271,7 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
min = fill; /* save offset to next table */
|
min = fill; /* save offset to next table */
|
||||||
do {
|
do {
|
||||||
fill -= incr;
|
fill -= incr;
|
||||||
table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
|
tbl[next_space + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val | 0;
|
||||||
} while (fill !== 0);
|
} while (fill !== 0);
|
||||||
|
|
||||||
/* backwards increment the len-bit code huff */
|
/* backwards increment the len-bit code huff */
|
||||||
|
@ -280,7 +289,9 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
/* go to next symbol, update count, len */
|
/* go to next symbol, update count, len */
|
||||||
sym++;
|
sym++;
|
||||||
if (--count[len] === 0) {
|
if (--count[len] === 0) {
|
||||||
if (len === max) { break; }
|
if (len === max) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
len = lens[lens_index + work[sym]];
|
len = lens[lens_index + work[sym]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,22 +303,23 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment past last table */
|
/* increment past last table */
|
||||||
next += min; /* here min is 1 << curr */
|
next_space += min; /* here min is 1 << curr */
|
||||||
|
|
||||||
/* determine length of next table */
|
/* determine length of next table */
|
||||||
curr = len - drop;
|
curr = len - drop;
|
||||||
left = 1 << curr;
|
left = 1 << curr;
|
||||||
while (curr + drop < max) {
|
while (curr + drop < max) {
|
||||||
left -= count[curr + drop];
|
left -= count[curr + drop];
|
||||||
if (left <= 0) { break; }
|
if (left <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
curr++;
|
curr++;
|
||||||
left <<= 1;
|
left <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for enough space */
|
/* check for enough space */
|
||||||
used += 1 << curr;
|
used += 1 << curr;
|
||||||
if ((type === LENS && used > ENOUGH_LENS) ||
|
if ((ty === LENS && used > ENOUGH_LENS) || (ty === DISTS && used > ENOUGH_DISTS)) {
|
||||||
(type === DISTS && used > ENOUGH_DISTS)) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +328,7 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
/*table.op[low] = curr;
|
/*table.op[low] = curr;
|
||||||
table.bits[low] = root;
|
table.bits[low] = root;
|
||||||
table.val[low] = next - opts.table_index;*/
|
table.val[low] = next - opts.table_index;*/
|
||||||
table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
|
tbl[low] = (root << 24) | (curr << 16) | (next_space - table_index) | 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +339,7 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
//table.op[next + huff] = 64; /* invalid code marker */
|
//table.op[next + huff] = 64; /* invalid code marker */
|
||||||
//table.bits[next + huff] = len - drop;
|
//table.bits[next + huff] = len - drop;
|
||||||
//table.val[next + huff] = 0;
|
//table.val[next + huff] = 0;
|
||||||
table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
|
tbl[next_space + huff] = ((len - drop) << 24) | (64 << 16) | 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set return parameters */
|
/* set return parameters */
|
||||||
|
@ -335,6 +347,3 @@ const inflate_table = (type, lens, lens_index, codes, table, table_index, work,
|
||||||
opts.bits = root;
|
opts.bits = root;
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = inflate_table;
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -19,14 +19,14 @@
|
||||||
// misrepresented as being the original software.
|
// misrepresented as being the original software.
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
module.exports = {
|
export default {
|
||||||
2: 'need dictionary', /* Z_NEED_DICT 2 */
|
2: "need dictionary" /* Z_NEED_DICT 2 */,
|
||||||
1: 'stream end', /* Z_STREAM_END 1 */
|
1: "stream end" /* Z_STREAM_END 1 */,
|
||||||
0: '', /* Z_OK 0 */
|
0: "" /* Z_OK 0 */,
|
||||||
'-1': 'file error', /* Z_ERRNO (-1) */
|
[-1]: "file error" /* Z_ERRNO (-1) */,
|
||||||
'-2': 'stream error', /* Z_STREAM_ERROR (-2) */
|
[-2]: "stream error" /* Z_STREAM_ERROR (-2) */,
|
||||||
'-3': 'data error', /* Z_DATA_ERROR (-3) */
|
[-3]: "data error" /* Z_DATA_ERROR (-3) */,
|
||||||
'-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */
|
[-4]: "insufficient memory" /* Z_MEM_ERROR (-4) */,
|
||||||
'-5': 'buffer error', /* Z_BUF_ERROR (-5) */
|
[-5]: "buffer error" /* Z_BUF_ERROR (-5) */,
|
||||||
'-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */
|
[-6]: "incompatible version" /* Z_VERSION_ERROR (-6) */,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { NumericArrayLike, Uint16Array, Uint8Array } from "../utils/buffs";
|
||||||
|
import { DeflateState } from "./deflate";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -24,7 +27,6 @@
|
||||||
/* Public constants ==========================================================*/
|
/* Public constants ==========================================================*/
|
||||||
/* ===========================================================================*/
|
/* ===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
//const Z_FILTERED = 1;
|
//const Z_FILTERED = 1;
|
||||||
//const Z_HUFFMAN_ONLY = 2;
|
//const Z_HUFFMAN_ONLY = 2;
|
||||||
//const Z_RLE = 3;
|
//const Z_RLE = 3;
|
||||||
|
@ -39,9 +41,6 @@ const Z_UNKNOWN = 2;
|
||||||
|
|
||||||
/*============================================================================*/
|
/*============================================================================*/
|
||||||
|
|
||||||
|
|
||||||
function zero(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } }
|
|
||||||
|
|
||||||
// From zutil.h
|
// From zutil.h
|
||||||
|
|
||||||
const STORED_BLOCK = 0;
|
const STORED_BLOCK = 0;
|
||||||
|
@ -82,7 +81,6 @@ const MAX_BITS = 15;
|
||||||
const Buf_size = 16;
|
const Buf_size = 16;
|
||||||
/* size of bit buffer in bi_buf */
|
/* size of bit buffer in bi_buf */
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
|
@ -103,17 +101,19 @@ const REPZ_11_138 = 18;
|
||||||
/* repeat a zero length 11-138 times (7 bits of repeat count) */
|
/* repeat a zero length 11-138 times (7 bits of repeat count) */
|
||||||
|
|
||||||
/* eslint-disable comma-spacing,array-bracket-spacing */
|
/* eslint-disable comma-spacing,array-bracket-spacing */
|
||||||
const extra_lbits = /* extra bits for each length code */
|
const extra_lbits =
|
||||||
|
/* extra bits for each length code */
|
||||||
new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]);
|
new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]);
|
||||||
|
|
||||||
const extra_dbits = /* extra bits for each distance code */
|
const extra_dbits =
|
||||||
|
/* extra bits for each distance code */
|
||||||
new Uint8Array([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]);
|
new Uint8Array([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]);
|
||||||
|
|
||||||
const extra_blbits = /* extra bits for each bit length code */
|
const extra_blbits =
|
||||||
|
/* extra bits for each bit length code */
|
||||||
new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]);
|
new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]);
|
||||||
|
|
||||||
const bl_order =
|
const bl_order = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
||||||
new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);
|
|
||||||
/* eslint-enable comma-spacing,array-bracket-spacing */
|
/* eslint-enable comma-spacing,array-bracket-spacing */
|
||||||
|
|
||||||
/* The lengths of the bit length codes are sent in order of decreasing
|
/* The lengths of the bit length codes are sent in order of decreasing
|
||||||
|
@ -129,91 +129,79 @@ const bl_order =
|
||||||
const DIST_CODE_LEN = 512; /* see definition of array dist_code below */
|
const DIST_CODE_LEN = 512; /* see definition of array dist_code below */
|
||||||
|
|
||||||
// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
|
// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
|
||||||
const static_ltree = new Array((L_CODES + 2) * 2);
|
const static_ltree = table.create((L_CODES + 2) * 2, 0);
|
||||||
zero(static_ltree);
|
|
||||||
/* The static literal tree. Since the bit lengths are imposed, there is no
|
/* The static literal tree. Since the bit lengths are imposed, there is no
|
||||||
* need for the L_CODES extra codes used during heap construction. However
|
* need for the L_CODES extra codes used during heap construction. However
|
||||||
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init
|
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init
|
||||||
* below).
|
* below).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const static_dtree = new Array(D_CODES * 2);
|
const static_dtree = table.create(D_CODES * 2, 0);
|
||||||
zero(static_dtree);
|
|
||||||
/* The static distance tree. (Actually a trivial tree since all codes use
|
/* The static distance tree. (Actually a trivial tree since all codes use
|
||||||
* 5 bits.)
|
* 5 bits.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const _dist_code = new Array(DIST_CODE_LEN);
|
const _dist_code = table.create(DIST_CODE_LEN, 0);
|
||||||
zero(_dist_code);
|
|
||||||
/* Distance codes. The first 256 values correspond to the distances
|
/* Distance codes. The first 256 values correspond to the distances
|
||||||
* 3 .. 258, the last 256 values correspond to the top 8 bits of
|
* 3 .. 258, the last 256 values correspond to the top 8 bits of
|
||||||
* the 15 bit distances.
|
* the 15 bit distances.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
|
const _length_code = table.create(MAX_MATCH - MIN_MATCH + 1, 0);
|
||||||
zero(_length_code);
|
|
||||||
/* length code for each normalized match length (0 == MIN_MATCH) */
|
/* length code for each normalized match length (0 == MIN_MATCH) */
|
||||||
|
|
||||||
const base_length = new Array(LENGTH_CODES);
|
const base_length = table.create(LENGTH_CODES, 0);
|
||||||
zero(base_length);
|
|
||||||
/* First normalized length for each code (0 = MIN_MATCH) */
|
/* First normalized length for each code (0 = MIN_MATCH) */
|
||||||
|
|
||||||
const base_dist = new Array(D_CODES);
|
const base_dist = table.create(D_CODES, 0);
|
||||||
zero(base_dist);
|
|
||||||
/* First normalized distance for each code (0 = distance of 1) */
|
/* First normalized distance for each code (0 = distance of 1) */
|
||||||
|
|
||||||
|
class StaticTreeDesc {
|
||||||
function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
|
public has_stree: boolean;
|
||||||
|
constructor(
|
||||||
this.static_tree = static_tree; /* static tree or NULL */
|
public static_tree: Array<number>,
|
||||||
this.extra_bits = extra_bits; /* extra bits for each code or NULL */
|
public extra_bits: Uint8Array,
|
||||||
this.extra_base = extra_base; /* base index for extra_bits */
|
public extra_base: number,
|
||||||
this.elems = elems; /* max number of elements in the tree */
|
public elems: number,
|
||||||
this.max_length = max_length; /* max bit length for the codes */
|
public max_length: number,
|
||||||
|
) {
|
||||||
// show if `static_tree` has data or dummy - needed for monomorphic objects
|
this.has_stree = static_tree && static_tree.size() > 0;
|
||||||
this.has_stree = static_tree && static_tree.length;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let static_l_desc: StaticTreeDesc;
|
||||||
|
let static_d_desc: StaticTreeDesc;
|
||||||
|
let static_bl_desc: StaticTreeDesc;
|
||||||
|
|
||||||
let static_l_desc;
|
export class TreeDesc {
|
||||||
let static_d_desc;
|
public max_code = 0; /* largest code with non zero frequency */
|
||||||
let static_bl_desc;
|
constructor(
|
||||||
|
public dyn_tree: Uint16Array,
|
||||||
|
public stat_desc: StaticTreeDesc,
|
||||||
function TreeDesc(dyn_tree, stat_desc) {
|
) {}
|
||||||
this.dyn_tree = dyn_tree; /* the dynamic tree */
|
|
||||||
this.max_code = 0; /* largest code with non zero frequency */
|
|
||||||
this.stat_desc = stat_desc; /* the corresponding static tree */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const d_code = (dist: number) => {
|
||||||
|
|
||||||
const d_code = (dist) => {
|
|
||||||
|
|
||||||
return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
|
return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Output a short LSB first on the stream.
|
* Output a short LSB first on the stream.
|
||||||
* IN assertion: there is enough room in pendingBuf.
|
* IN assertion: there is enough room in pendingBuf.
|
||||||
*/
|
*/
|
||||||
const put_short = (s, w) => {
|
const put_short = (s: DeflateState, w: number) => {
|
||||||
// put_byte(s, (uch)((w) & 0xff));
|
// put_byte(s, (uch)((w) & 0xff));
|
||||||
// put_byte(s, (uch)((ush)(w) >> 8));
|
// put_byte(s, (uch)((ush)(w) >> 8));
|
||||||
s.pending_buf[s.pending++] = (w) & 0xff;
|
s.pending_buf[s.pending++] = w & 0xff;
|
||||||
s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
|
s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send a value on a given number of bits.
|
* Send a value on a given number of bits.
|
||||||
* IN assertion: length <= 16 and value fits in length bits.
|
* IN assertion: length <= 16 and value fits in length bits.
|
||||||
*/
|
*/
|
||||||
const send_bits = (s, value, length) => {
|
const send_bits = (s: DeflateState, value: number, length: number) => {
|
||||||
|
if (s.bi_valid > Buf_size - length) {
|
||||||
if (s.bi_valid > (Buf_size - length)) {
|
|
||||||
s.bi_buf |= (value << s.bi_valid) & 0xffff;
|
s.bi_buf |= (value << s.bi_valid) & 0xffff;
|
||||||
put_short(s, s.bi_buf);
|
put_short(s, s.bi_buf);
|
||||||
s.bi_buf = value >> (Buf_size - s.bi_valid);
|
s.bi_buf = value >> (Buf_size - s.bi_valid);
|
||||||
|
@ -224,20 +212,16 @@ const send_bits = (s, value, length) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const send_code = (s: DeflateState, c: number, tree: NumericArrayLike) => {
|
||||||
const send_code = (s, c, tree) => {
|
|
||||||
|
|
||||||
send_bits(s, tree[c * 2] /*.Code*/, tree[c * 2 + 1] /*.Len*/);
|
send_bits(s, tree[c * 2] /*.Code*/, tree[c * 2 + 1] /*.Len*/);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Reverse the first len bits of a code, using straightforward code (a faster
|
* Reverse the first len bits of a code, using straightforward code (a faster
|
||||||
* method would use a table)
|
* method would use a table)
|
||||||
* IN assertion: 1 <= len <= 15
|
* IN assertion: 1 <= len <= 15
|
||||||
*/
|
*/
|
||||||
const bi_reverse = (code, len) => {
|
const bi_reverse = (code: number, len: number) => {
|
||||||
|
|
||||||
let res = 0;
|
let res = 0;
|
||||||
do {
|
do {
|
||||||
res |= code & 1;
|
res |= code & 1;
|
||||||
|
@ -247,17 +231,14 @@ const bi_reverse = (code, len) => {
|
||||||
return res >>> 1;
|
return res >>> 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Flush the bit buffer, keeping at most 7 bits in it.
|
* Flush the bit buffer, keeping at most 7 bits in it.
|
||||||
*/
|
*/
|
||||||
const bi_flush = (s) => {
|
const bi_flush = (s: DeflateState) => {
|
||||||
|
|
||||||
if (s.bi_valid === 16) {
|
if (s.bi_valid === 16) {
|
||||||
put_short(s, s.bi_buf);
|
put_short(s, s.bi_buf);
|
||||||
s.bi_buf = 0;
|
s.bi_buf = 0;
|
||||||
s.bi_valid = 0;
|
s.bi_valid = 0;
|
||||||
|
|
||||||
} else if (s.bi_valid >= 8) {
|
} else if (s.bi_valid >= 8) {
|
||||||
s.pending_buf[s.pending++] = s.bi_buf & 0xff;
|
s.pending_buf[s.pending++] = s.bi_buf & 0xff;
|
||||||
s.bi_buf >>= 8;
|
s.bi_buf >>= 8;
|
||||||
|
@ -265,7 +246,6 @@ const bi_flush = (s) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Compute the optimal bit lengths for a tree and update the total bit length
|
* Compute the optimal bit lengths for a tree and update the total bit length
|
||||||
* for the current block.
|
* for the current block.
|
||||||
|
@ -276,7 +256,7 @@ const bi_flush = (s) => {
|
||||||
* The length opt_len is updated; static_len is also updated if stree is
|
* The length opt_len is updated; static_len is also updated if stree is
|
||||||
* not null.
|
* not null.
|
||||||
*/
|
*/
|
||||||
const gen_bitlen = (s, desc) => {
|
const gen_bitlen = (s: DeflateState, desc: TreeDesc) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// tree_desc *desc; /* the tree descriptor */
|
// tree_desc *desc; /* the tree descriptor */
|
||||||
|
|
||||||
|
@ -313,7 +293,9 @@ const gen_bitlen = (s, desc) => {
|
||||||
tree[n * 2 + 1] /*.Len*/ = bits;
|
tree[n * 2 + 1] /*.Len*/ = bits;
|
||||||
/* We overwrite tree[n].Dad which is no longer needed */
|
/* We overwrite tree[n].Dad which is no longer needed */
|
||||||
|
|
||||||
if (n > max_code) { continue; } /* not a leaf node */
|
if (n > max_code) {
|
||||||
|
continue;
|
||||||
|
} /* not a leaf node */
|
||||||
|
|
||||||
s.bl_count[bits]++;
|
s.bl_count[bits]++;
|
||||||
xbits = 0;
|
xbits = 0;
|
||||||
|
@ -326,7 +308,9 @@ const gen_bitlen = (s, desc) => {
|
||||||
s.static_len += f * (stree[n * 2 + 1] /*.Len*/ + xbits);
|
s.static_len += f * (stree[n * 2 + 1] /*.Len*/ + xbits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (overflow === 0) { return; }
|
if (overflow === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Tracev((stderr,"\nbit length overflow\n"));
|
// Tracev((stderr,"\nbit length overflow\n"));
|
||||||
/* This happens for example on obj2 and pic of the Calgary corpus */
|
/* This happens for example on obj2 and pic of the Calgary corpus */
|
||||||
|
@ -334,7 +318,9 @@ const gen_bitlen = (s, desc) => {
|
||||||
/* Find the first bit length which could increase: */
|
/* Find the first bit length which could increase: */
|
||||||
do {
|
do {
|
||||||
bits = max_length - 1;
|
bits = max_length - 1;
|
||||||
while (s.bl_count[bits] === 0) { bits--; }
|
while (s.bl_count[bits] === 0) {
|
||||||
|
bits--;
|
||||||
|
}
|
||||||
s.bl_count[bits]--; /* move one leaf down the tree */
|
s.bl_count[bits]--; /* move one leaf down the tree */
|
||||||
s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
|
s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
|
||||||
s.bl_count[max_length]--;
|
s.bl_count[max_length]--;
|
||||||
|
@ -353,10 +339,12 @@ const gen_bitlen = (s, desc) => {
|
||||||
n = s.bl_count[bits];
|
n = s.bl_count[bits];
|
||||||
while (n !== 0) {
|
while (n !== 0) {
|
||||||
m = s.heap[--h];
|
m = s.heap[--h];
|
||||||
if (m > max_code) { continue; }
|
if (m > max_code) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (tree[m * 2 + 1] /*.Len*/ !== bits) {
|
if (tree[m * 2 + 1] /*.Len*/ !== bits) {
|
||||||
// Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
|
// Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
|
||||||
s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
|
s.opt_len += (bits - tree[m * 2 + 1]) /*.Len*/ * tree[m * 2] /*.Freq*/;
|
||||||
tree[m * 2 + 1] /*.Len*/ = bits;
|
tree[m * 2 + 1] /*.Len*/ = bits;
|
||||||
}
|
}
|
||||||
n--;
|
n--;
|
||||||
|
@ -364,7 +352,6 @@ const gen_bitlen = (s, desc) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Generate the codes for a given tree and bit counts (which need not be
|
* Generate the codes for a given tree and bit counts (which need not be
|
||||||
* optimal).
|
* optimal).
|
||||||
|
@ -373,12 +360,12 @@ const gen_bitlen = (s, desc) => {
|
||||||
* OUT assertion: the field code is set for all tree elements of non
|
* OUT assertion: the field code is set for all tree elements of non
|
||||||
* zero code length.
|
* zero code length.
|
||||||
*/
|
*/
|
||||||
const gen_codes = (tree, max_code, bl_count) => {
|
const gen_codes = (tree: NumericArrayLike, max_code: number, bl_count: NumericArrayLike) => {
|
||||||
// ct_data *tree; /* the tree to decorate */
|
// ct_data *tree; /* the tree to decorate */
|
||||||
// int max_code; /* largest code with non zero frequency */
|
// int max_code; /* largest code with non zero frequency */
|
||||||
// ushf *bl_count; /* number of codes at each bit length */
|
// ushf *bl_count; /* number of codes at each bit length */
|
||||||
|
|
||||||
const next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
|
const next_code = new Array<number>(MAX_BITS + 1); /* next code value for each bit length */
|
||||||
let code = 0; /* running code value */
|
let code = 0; /* running code value */
|
||||||
let bits; /* bit index */
|
let bits; /* bit index */
|
||||||
let n; /* code index */
|
let n; /* code index */
|
||||||
|
@ -398,8 +385,10 @@ const gen_codes = (tree, max_code, bl_count) => {
|
||||||
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
|
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
|
||||||
|
|
||||||
for (n = 0; n <= max_code; n++) {
|
for (n = 0; n <= max_code; n++) {
|
||||||
let len = tree[n * 2 + 1]/*.Len*/;
|
let len = tree[n * 2 + 1]; /*.Len*/
|
||||||
if (len === 0) { continue; }
|
if (len === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
/* Now reverse the bits */
|
/* Now reverse the bits */
|
||||||
tree[n * 2] /*.Code*/ = bi_reverse(next_code[len]++, len);
|
tree[n * 2] /*.Code*/ = bi_reverse(next_code[len]++, len);
|
||||||
|
|
||||||
|
@ -408,18 +397,16 @@ const gen_codes = (tree, max_code, bl_count) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Initialize the various 'constant' tables.
|
* Initialize the various 'constant' tables.
|
||||||
*/
|
*/
|
||||||
const tr_static_init = () => {
|
const tr_static_init = () => {
|
||||||
|
|
||||||
let n; /* iterates over tree elements */
|
let n; /* iterates over tree elements */
|
||||||
let bits; /* bit counter */
|
let bits; /* bit counter */
|
||||||
let length; /* length value */
|
let length; /* length value */
|
||||||
let code; /* code value */
|
let code; /* code value */
|
||||||
let dist; /* distance index */
|
let dist; /* distance index */
|
||||||
const bl_count = new Array(MAX_BITS + 1);
|
const bl_count = new Array<number>(MAX_BITS + 1);
|
||||||
/* number of codes at each bit length for an optimal tree */
|
/* number of codes at each bit length for an optimal tree */
|
||||||
|
|
||||||
// do check in _tr_init()
|
// do check in _tr_init()
|
||||||
|
@ -438,7 +425,7 @@ const tr_static_init = () => {
|
||||||
length = 0;
|
length = 0;
|
||||||
for (code = 0; code < LENGTH_CODES - 1; code++) {
|
for (code = 0; code < LENGTH_CODES - 1; code++) {
|
||||||
base_length[code] = length;
|
base_length[code] = length;
|
||||||
for (n = 0; n < (1 << extra_lbits[code]); n++) {
|
for (n = 0; n < 1 << extra_lbits[code]; n++) {
|
||||||
_length_code[length++] = code;
|
_length_code[length++] = code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,7 +440,7 @@ const tr_static_init = () => {
|
||||||
dist = 0;
|
dist = 0;
|
||||||
for (code = 0; code < 16; code++) {
|
for (code = 0; code < 16; code++) {
|
||||||
base_dist[code] = dist;
|
base_dist[code] = dist;
|
||||||
for (n = 0; n < (1 << extra_dbits[code]); n++) {
|
for (n = 0; n < 1 << extra_dbits[code]; n++) {
|
||||||
_dist_code[dist++] = code;
|
_dist_code[dist++] = code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -461,7 +448,7 @@ const tr_static_init = () => {
|
||||||
dist >>= 7; /* from now on, all distances are divided by 128 */
|
dist >>= 7; /* from now on, all distances are divided by 128 */
|
||||||
for (; code < D_CODES; code++) {
|
for (; code < D_CODES; code++) {
|
||||||
base_dist[code] = dist << 7;
|
base_dist[code] = dist << 7;
|
||||||
for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
|
for (n = 0; n < 1 << (extra_dbits[code] - 7); n++) {
|
||||||
_dist_code[256 + dist++] = code;
|
_dist_code[256 + dist++] = code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,30 +500,32 @@ const tr_static_init = () => {
|
||||||
//static_init_done = true;
|
//static_init_done = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Initialize a new block.
|
* Initialize a new block.
|
||||||
*/
|
*/
|
||||||
const init_block = (s) => {
|
const init_block = (s: DeflateState) => {
|
||||||
|
|
||||||
let n; /* iterates over tree elements */
|
let n; /* iterates over tree elements */
|
||||||
|
|
||||||
/* Initialize the trees. */
|
/* Initialize the trees. */
|
||||||
for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }
|
for (n = 0; n < L_CODES; n++) {
|
||||||
for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }
|
s.dyn_ltree[n * 2] /*.Freq*/ = 0;
|
||||||
for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }
|
}
|
||||||
|
for (n = 0; n < D_CODES; n++) {
|
||||||
|
s.dyn_dtree[n * 2] /*.Freq*/ = 0;
|
||||||
|
}
|
||||||
|
for (n = 0; n < BL_CODES; n++) {
|
||||||
|
s.bl_tree[n * 2] /*.Freq*/ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
s.dyn_ltree[END_BLOCK * 2] /*.Freq*/ = 1;
|
s.dyn_ltree[END_BLOCK * 2] /*.Freq*/ = 1;
|
||||||
s.opt_len = s.static_len = 0;
|
s.opt_len = s.static_len = 0;
|
||||||
s.sym_next = s.matches = 0;
|
s.sym_next = s.matches = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Flush the bit buffer and align the output on a byte boundary
|
* Flush the bit buffer and align the output on a byte boundary
|
||||||
*/
|
*/
|
||||||
const bi_windup = (s) =>
|
const bi_windup = (s: DeflateState) => {
|
||||||
{
|
|
||||||
if (s.bi_valid > 8) {
|
if (s.bi_valid > 8) {
|
||||||
put_short(s, s.bi_buf);
|
put_short(s, s.bi_buf);
|
||||||
} else if (s.bi_valid > 0) {
|
} else if (s.bi_valid > 0) {
|
||||||
|
@ -551,12 +540,13 @@ const bi_windup = (s) =>
|
||||||
* Compares to subtrees, using the tree depth as tie breaker when
|
* Compares to subtrees, using the tree depth as tie breaker when
|
||||||
* the subtrees have equal frequency. This minimizes the worst case length.
|
* the subtrees have equal frequency. This minimizes the worst case length.
|
||||||
*/
|
*/
|
||||||
const smaller = (tree, n, m, depth) => {
|
const smaller = (tree: NumericArrayLike, n: number, m: number, depth: NumericArrayLike) => {
|
||||||
|
|
||||||
const _n2 = n * 2;
|
const _n2 = n * 2;
|
||||||
const _m2 = m * 2;
|
const _m2 = m * 2;
|
||||||
return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
|
return (
|
||||||
(tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));
|
tree[_n2] /*.Freq*/ < tree[_m2] /*.Freq*/ ||
|
||||||
|
(tree[_n2] /*.Freq*/ === tree[_m2] /*.Freq*/ && depth[n] <= depth[m])
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -565,7 +555,7 @@ const smaller = (tree, n, m, depth) => {
|
||||||
* when the heap property is re-established (each father smaller than its
|
* when the heap property is re-established (each father smaller than its
|
||||||
* two sons).
|
* two sons).
|
||||||
*/
|
*/
|
||||||
const pqdownheap = (s, tree, k) => {
|
const pqdownheap = (s: DeflateState, tree: NumericArrayLike, k: number) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// ct_data *tree; /* the tree to restore */
|
// ct_data *tree; /* the tree to restore */
|
||||||
// int k; /* node to move down */
|
// int k; /* node to move down */
|
||||||
|
@ -574,12 +564,13 @@ const pqdownheap = (s, tree, k) => {
|
||||||
let j = k << 1; /* left son of k */
|
let j = k << 1; /* left son of k */
|
||||||
while (j <= s.heap_len) {
|
while (j <= s.heap_len) {
|
||||||
/* Set j to the smallest of the two sons: */
|
/* Set j to the smallest of the two sons: */
|
||||||
if (j < s.heap_len &&
|
if (j < s.heap_len && smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
|
||||||
smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
|
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
/* Exit if v is smaller than both sons */
|
/* Exit if v is smaller than both sons */
|
||||||
if (smaller(tree, v, s.heap[j], s.depth)) { break; }
|
if (smaller(tree, v, s.heap[j], s.depth)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Exchange v with the smallest son */
|
/* Exchange v with the smallest son */
|
||||||
s.heap[k] = s.heap[j];
|
s.heap[k] = s.heap[j];
|
||||||
|
@ -591,14 +582,13 @@ const pqdownheap = (s, tree, k) => {
|
||||||
s.heap[k] = v;
|
s.heap[k] = v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// inlined manually
|
// inlined manually
|
||||||
// const SMALLEST = 1;
|
// const SMALLEST = 1;
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send the block data compressed using the given Huffman trees
|
* Send the block data compressed using the given Huffman trees
|
||||||
*/
|
*/
|
||||||
const compress_block = (s, ltree, dtree) => {
|
const compress_block = (s: DeflateState, ltree: NumericArrayLike, dtree: NumericArrayLike) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// const ct_data *ltree; /* literal tree */
|
// const ct_data *ltree; /* literal tree */
|
||||||
// const ct_data *dtree; /* distance tree */
|
// const ct_data *dtree; /* distance tree */
|
||||||
|
@ -640,14 +630,12 @@ const compress_block = (s, ltree, dtree) => {
|
||||||
|
|
||||||
/* Check that the overlay between pending_buf and sym_buf is ok: */
|
/* Check that the overlay between pending_buf and sym_buf is ok: */
|
||||||
//Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
|
//Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
|
||||||
|
|
||||||
} while (sx < s.sym_next);
|
} while (sx < s.sym_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_code(s, END_BLOCK, ltree);
|
send_code(s, END_BLOCK, ltree);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Construct one Huffman tree and assigns the code bit strings and lengths.
|
* Construct one Huffman tree and assigns the code bit strings and lengths.
|
||||||
* Update the total bit length for the current block.
|
* Update the total bit length for the current block.
|
||||||
|
@ -656,7 +644,7 @@ const compress_block = (s, ltree, dtree) => {
|
||||||
* and corresponding code. The length opt_len is updated; static_len is
|
* and corresponding code. The length opt_len is updated; static_len is
|
||||||
* also updated if stree is not null. The field max_code is set.
|
* also updated if stree is not null. The field max_code is set.
|
||||||
*/
|
*/
|
||||||
const build_tree = (s, desc) => {
|
const build_tree = (s: DeflateState, desc: TreeDesc) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// tree_desc *desc; /* the tree descriptor */
|
// tree_desc *desc; /* the tree descriptor */
|
||||||
|
|
||||||
|
@ -679,7 +667,6 @@ const build_tree = (s, desc) => {
|
||||||
if (tree[n * 2] /*.Freq*/ !== 0) {
|
if (tree[n * 2] /*.Freq*/ !== 0) {
|
||||||
s.heap[++s.heap_len] = max_code = n;
|
s.heap[++s.heap_len] = max_code = n;
|
||||||
s.depth[n] = 0;
|
s.depth[n] = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tree[n * 2 + 1] /*.Len*/ = 0;
|
tree[n * 2 + 1] /*.Len*/ = 0;
|
||||||
}
|
}
|
||||||
|
@ -691,7 +678,7 @@ const build_tree = (s, desc) => {
|
||||||
* two codes of non zero frequency.
|
* two codes of non zero frequency.
|
||||||
*/
|
*/
|
||||||
while (s.heap_len < 2) {
|
while (s.heap_len < 2) {
|
||||||
node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
|
node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
|
||||||
tree[node * 2] /*.Freq*/ = 1;
|
tree[node * 2] /*.Freq*/ = 1;
|
||||||
s.depth[node] = 0;
|
s.depth[node] = 0;
|
||||||
s.opt_len--;
|
s.opt_len--;
|
||||||
|
@ -706,7 +693,9 @@ const build_tree = (s, desc) => {
|
||||||
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
|
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
|
||||||
* establish sub-heaps of increasing lengths:
|
* establish sub-heaps of increasing lengths:
|
||||||
*/
|
*/
|
||||||
for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }
|
for (n = s.heap_len >> 1 /*int /2*/; n >= 1; n--) {
|
||||||
|
pqdownheap(s, tree, n);
|
||||||
|
}
|
||||||
|
|
||||||
/* Construct the Huffman tree by repeatedly combining the least two
|
/* Construct the Huffman tree by repeatedly combining the least two
|
||||||
* frequent nodes.
|
* frequent nodes.
|
||||||
|
@ -733,7 +722,6 @@ const build_tree = (s, desc) => {
|
||||||
/* and insert the new node in the heap */
|
/* and insert the new node in the heap */
|
||||||
s.heap[1 /*SMALLEST*/] = node++;
|
s.heap[1 /*SMALLEST*/] = node++;
|
||||||
pqdownheap(s, tree, 1 /*SMALLEST*/);
|
pqdownheap(s, tree, 1 /*SMALLEST*/);
|
||||||
|
|
||||||
} while (s.heap_len >= 2);
|
} while (s.heap_len >= 2);
|
||||||
|
|
||||||
s.heap[--s.heap_max] = s.heap[1 /*SMALLEST*/];
|
s.heap[--s.heap_max] = s.heap[1 /*SMALLEST*/];
|
||||||
|
@ -747,12 +735,11 @@ const build_tree = (s, desc) => {
|
||||||
gen_codes(tree, max_code, s.bl_count);
|
gen_codes(tree, max_code, s.bl_count);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Scan a literal or distance tree to determine the frequencies of the codes
|
* Scan a literal or distance tree to determine the frequencies of the codes
|
||||||
* in the bit length tree.
|
* in the bit length tree.
|
||||||
*/
|
*/
|
||||||
const scan_tree = (s, tree, max_code) => {
|
const scan_tree = (s: DeflateState, tree: NumericArrayLike, max_code: number) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// ct_data *tree; /* the tree to be scanned */
|
// ct_data *tree; /* the tree to be scanned */
|
||||||
// int max_code; /* and its largest code of non zero frequency */
|
// int max_code; /* and its largest code of non zero frequency */
|
||||||
|
@ -761,7 +748,7 @@ const scan_tree = (s, tree, max_code) => {
|
||||||
let prevlen = -1; /* last emitted length */
|
let prevlen = -1; /* last emitted length */
|
||||||
let curlen; /* length of current code */
|
let curlen; /* length of current code */
|
||||||
|
|
||||||
let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
|
let nextlen = tree[0 * 2 + 1]; /*.Len*/ /* length of next code */
|
||||||
|
|
||||||
let count = 0; /* repeat count of the current code */
|
let count = 0; /* repeat count of the current code */
|
||||||
let max_count = 7; /* max repeat count */
|
let max_count = 7; /* max repeat count */
|
||||||
|
@ -779,18 +766,15 @@ const scan_tree = (s, tree, max_code) => {
|
||||||
|
|
||||||
if (++count < max_count && curlen === nextlen) {
|
if (++count < max_count && curlen === nextlen) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (count < min_count) {
|
} else if (count < min_count) {
|
||||||
s.bl_tree[curlen * 2] /*.Freq*/ += count;
|
s.bl_tree[curlen * 2] /*.Freq*/ += count;
|
||||||
|
|
||||||
} else if (curlen !== 0) {
|
} else if (curlen !== 0) {
|
||||||
|
if (curlen !== prevlen) {
|
||||||
if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }
|
s.bl_tree[curlen * 2] /*.Freq*/++;
|
||||||
|
}
|
||||||
s.bl_tree[REP_3_6 * 2] /*.Freq*/++;
|
s.bl_tree[REP_3_6 * 2] /*.Freq*/++;
|
||||||
|
|
||||||
} else if (count <= 10) {
|
} else if (count <= 10) {
|
||||||
s.bl_tree[REPZ_3_10 * 2] /*.Freq*/++;
|
s.bl_tree[REPZ_3_10 * 2] /*.Freq*/++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
s.bl_tree[REPZ_11_138 * 2] /*.Freq*/++;
|
s.bl_tree[REPZ_11_138 * 2] /*.Freq*/++;
|
||||||
}
|
}
|
||||||
|
@ -801,11 +785,9 @@ const scan_tree = (s, tree, max_code) => {
|
||||||
if (nextlen === 0) {
|
if (nextlen === 0) {
|
||||||
max_count = 138;
|
max_count = 138;
|
||||||
min_count = 3;
|
min_count = 3;
|
||||||
|
|
||||||
} else if (curlen === nextlen) {
|
} else if (curlen === nextlen) {
|
||||||
max_count = 6;
|
max_count = 6;
|
||||||
min_count = 3;
|
min_count = 3;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
max_count = 7;
|
max_count = 7;
|
||||||
min_count = 4;
|
min_count = 4;
|
||||||
|
@ -813,12 +795,11 @@ const scan_tree = (s, tree, max_code) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send a literal or distance tree in compressed form, using the codes in
|
* Send a literal or distance tree in compressed form, using the codes in
|
||||||
* bl_tree.
|
* bl_tree.
|
||||||
*/
|
*/
|
||||||
const send_tree = (s, tree, max_code) => {
|
const send_tree = (s: DeflateState, tree: NumericArrayLike, max_code: number) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// ct_data *tree; /* the tree to be scanned */
|
// ct_data *tree; /* the tree to be scanned */
|
||||||
// int max_code; /* and its largest code of non zero frequency */
|
// int max_code; /* and its largest code of non zero frequency */
|
||||||
|
@ -827,7 +808,7 @@ const send_tree = (s, tree, max_code) => {
|
||||||
let prevlen = -1; /* last emitted length */
|
let prevlen = -1; /* last emitted length */
|
||||||
let curlen; /* length of current code */
|
let curlen; /* length of current code */
|
||||||
|
|
||||||
let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
|
let nextlen = tree[0 * 2 + 1]; /*.Len*/ /* length of next code */
|
||||||
|
|
||||||
let count = 0; /* repeat count of the current code */
|
let count = 0; /* repeat count of the current code */
|
||||||
let max_count = 7; /* max repeat count */
|
let max_count = 7; /* max repeat count */
|
||||||
|
@ -845,10 +826,10 @@ const send_tree = (s, tree, max_code) => {
|
||||||
|
|
||||||
if (++count < max_count && curlen === nextlen) {
|
if (++count < max_count && curlen === nextlen) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (count < min_count) {
|
} else if (count < min_count) {
|
||||||
do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
|
do {
|
||||||
|
send_code(s, curlen, s.bl_tree);
|
||||||
|
} while (--count !== 0);
|
||||||
} else if (curlen !== 0) {
|
} else if (curlen !== 0) {
|
||||||
if (curlen !== prevlen) {
|
if (curlen !== prevlen) {
|
||||||
send_code(s, curlen, s.bl_tree);
|
send_code(s, curlen, s.bl_tree);
|
||||||
|
@ -857,11 +838,9 @@ const send_tree = (s, tree, max_code) => {
|
||||||
//Assert(count >= 3 && count <= 6, " 3_6?");
|
//Assert(count >= 3 && count <= 6, " 3_6?");
|
||||||
send_code(s, REP_3_6, s.bl_tree);
|
send_code(s, REP_3_6, s.bl_tree);
|
||||||
send_bits(s, count - 3, 2);
|
send_bits(s, count - 3, 2);
|
||||||
|
|
||||||
} else if (count <= 10) {
|
} else if (count <= 10) {
|
||||||
send_code(s, REPZ_3_10, s.bl_tree);
|
send_code(s, REPZ_3_10, s.bl_tree);
|
||||||
send_bits(s, count - 3, 3);
|
send_bits(s, count - 3, 3);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
send_code(s, REPZ_11_138, s.bl_tree);
|
send_code(s, REPZ_11_138, s.bl_tree);
|
||||||
send_bits(s, count - 11, 7);
|
send_bits(s, count - 11, 7);
|
||||||
|
@ -872,11 +851,9 @@ const send_tree = (s, tree, max_code) => {
|
||||||
if (nextlen === 0) {
|
if (nextlen === 0) {
|
||||||
max_count = 138;
|
max_count = 138;
|
||||||
min_count = 3;
|
min_count = 3;
|
||||||
|
|
||||||
} else if (curlen === nextlen) {
|
} else if (curlen === nextlen) {
|
||||||
max_count = 6;
|
max_count = 6;
|
||||||
min_count = 3;
|
min_count = 3;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
max_count = 7;
|
max_count = 7;
|
||||||
min_count = 4;
|
min_count = 4;
|
||||||
|
@ -884,13 +861,11 @@ const send_tree = (s, tree, max_code) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Construct the Huffman tree for the bit lengths and return the index in
|
* Construct the Huffman tree for the bit lengths and return the index in
|
||||||
* bl_order of the last bit length code to send.
|
* bl_order of the last bit length code to send.
|
||||||
*/
|
*/
|
||||||
const build_bl_tree = (s) => {
|
const build_bl_tree = (s: DeflateState) => {
|
||||||
|
|
||||||
let max_blindex; /* index of last bit length code of non zero freq */
|
let max_blindex; /* index of last bit length code of non zero freq */
|
||||||
|
|
||||||
/* Determine the bit length frequencies for literal and distance trees */
|
/* Determine the bit length frequencies for literal and distance trees */
|
||||||
|
@ -920,13 +895,12 @@ const build_bl_tree = (s) => {
|
||||||
return max_blindex;
|
return max_blindex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send the header for a block using dynamic Huffman trees: the counts, the
|
* Send the header for a block using dynamic Huffman trees: the counts, the
|
||||||
* lengths of the bit length codes, the literal tree and the distance tree.
|
* lengths of the bit length codes, the literal tree and the distance tree.
|
||||||
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
|
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
|
||||||
*/
|
*/
|
||||||
const send_all_trees = (s, lcodes, dcodes, blcodes) => {
|
const send_all_trees = (s: DeflateState, lcodes: number, dcodes: number, blcodes: number) => {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// int lcodes, dcodes, blcodes; /* number of codes for each tree */
|
// int lcodes, dcodes, blcodes; /* number of codes for each tree */
|
||||||
|
|
||||||
|
@ -952,7 +926,6 @@ const send_all_trees = (s, lcodes, dcodes, blcodes) => {
|
||||||
//Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
|
//Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Check if the data type is TEXT or BINARY, using the following algorithm:
|
* Check if the data type is TEXT or BINARY, using the following algorithm:
|
||||||
* - TEXT if the two conditions below are satisfied:
|
* - TEXT if the two conditions below are satisfied:
|
||||||
|
@ -966,7 +939,7 @@ const send_all_trees = (s, lcodes, dcodes, blcodes) => {
|
||||||
* (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
|
* (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
|
||||||
* IN assertion: the fields Freq of dyn_ltree are set.
|
* IN assertion: the fields Freq of dyn_ltree are set.
|
||||||
*/
|
*/
|
||||||
const detect_data_type = (s) => {
|
const detect_data_type = (s: DeflateState) => {
|
||||||
/* block_mask is the bit mask of block-listed bytes
|
/* block_mask is the bit mask of block-listed bytes
|
||||||
* set bits 0..6, 14..25, and 28..31
|
* set bits 0..6, 14..25, and 28..31
|
||||||
* 0xf3ffc07f = binary 11110011111111111100000001111111
|
* 0xf3ffc07f = binary 11110011111111111100000001111111
|
||||||
|
@ -976,14 +949,17 @@ const detect_data_type = (s) => {
|
||||||
|
|
||||||
/* Check for non-textual ("block-listed") bytes. */
|
/* Check for non-textual ("block-listed") bytes. */
|
||||||
for (n = 0; n <= 31; n++, block_mask >>>= 1) {
|
for (n = 0; n <= 31; n++, block_mask >>>= 1) {
|
||||||
if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {
|
if (block_mask & 1 && s.dyn_ltree[n * 2] /*.Freq*/ !== 0) {
|
||||||
return Z_BINARY;
|
return Z_BINARY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for textual ("allow-listed") bytes. */
|
/* Check for textual ("allow-listed") bytes. */
|
||||||
if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
|
if (
|
||||||
s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
|
s.dyn_ltree[9 * 2] /*.Freq*/ !== 0 ||
|
||||||
|
s.dyn_ltree[10 * 2] /*.Freq*/ !== 0 ||
|
||||||
|
s.dyn_ltree[13 * 2] /*.Freq*/ !== 0
|
||||||
|
) {
|
||||||
return Z_TEXT;
|
return Z_TEXT;
|
||||||
}
|
}
|
||||||
for (n = 32; n < LITERALS; n++) {
|
for (n = 32; n < LITERALS; n++) {
|
||||||
|
@ -998,15 +974,12 @@ const detect_data_type = (s) => {
|
||||||
return Z_BINARY;
|
return Z_BINARY;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let static_init_done = false;
|
let static_init_done = false;
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Initialize the tree data structures for a new zlib stream.
|
* Initialize the tree data structures for a new zlib stream.
|
||||||
*/
|
*/
|
||||||
const _tr_init = (s) =>
|
export function _tr_init(s: DeflateState) {
|
||||||
{
|
|
||||||
|
|
||||||
if (!static_init_done) {
|
if (!static_init_done) {
|
||||||
tr_static_init();
|
tr_static_init();
|
||||||
static_init_done = true;
|
static_init_done = true;
|
||||||
|
@ -1021,13 +994,12 @@ const _tr_init = (s) =>
|
||||||
|
|
||||||
/* Initialize the first block of the first file: */
|
/* Initialize the first block of the first file: */
|
||||||
init_block(s);
|
init_block(s);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send a stored block
|
* Send a stored block
|
||||||
*/
|
*/
|
||||||
const _tr_stored_block = (s, buf, stored_len, last) => {
|
export function _tr_stored_block(s: DeflateState, buf: number, stored_len: number, last: boolean) {
|
||||||
//DeflateState *s;
|
//DeflateState *s;
|
||||||
//charf *buf; /* input block */
|
//charf *buf; /* input block */
|
||||||
//ulg stored_len; /* length of input block */
|
//ulg stored_len; /* length of input block */
|
||||||
|
@ -1041,25 +1013,23 @@ const _tr_stored_block = (s, buf, stored_len, last) => {
|
||||||
s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending);
|
s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending);
|
||||||
}
|
}
|
||||||
s.pending += stored_len;
|
s.pending += stored_len;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send one empty static block to give enough lookahead for inflate.
|
* Send one empty static block to give enough lookahead for inflate.
|
||||||
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
||||||
*/
|
*/
|
||||||
const _tr_align = (s) => {
|
export function _tr_align(s: DeflateState) {
|
||||||
send_bits(s, STATIC_TREES << 1, 3);
|
send_bits(s, STATIC_TREES << 1, 3);
|
||||||
send_code(s, END_BLOCK, static_ltree);
|
send_code(s, END_BLOCK, static_ltree);
|
||||||
bi_flush(s);
|
bi_flush(s);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Determine the best encoding for the current block: dynamic trees, static
|
* Determine the best encoding for the current block: dynamic trees, static
|
||||||
* trees or store, and write out the encoded block.
|
* trees or store, and write out the encoded block.
|
||||||
*/
|
*/
|
||||||
const _tr_flush_block = (s, buf, stored_len, last) => {
|
export function _tr_flush_block(s: DeflateState, buf: number, stored_len: number, last: boolean) {
|
||||||
//DeflateState *s;
|
//DeflateState *s;
|
||||||
//charf *buf; /* input block, or NULL if too old */
|
//charf *buf; /* input block, or NULL if too old */
|
||||||
//ulg stored_len; /* length of input block */
|
//ulg stored_len; /* length of input block */
|
||||||
|
@ -1070,7 +1040,6 @@ const _tr_flush_block = (s, buf, stored_len, last) => {
|
||||||
|
|
||||||
/* Build the Huffman trees unless a stored block is forced */
|
/* Build the Huffman trees unless a stored block is forced */
|
||||||
if (s.level > 0) {
|
if (s.level > 0) {
|
||||||
|
|
||||||
/* Check if the file is binary or text */
|
/* Check if the file is binary or text */
|
||||||
if (s.strm.data_type === Z_UNKNOWN) {
|
if (s.strm.data_type === Z_UNKNOWN) {
|
||||||
s.strm.data_type = detect_data_type(s);
|
s.strm.data_type = detect_data_type(s);
|
||||||
|
@ -1101,14 +1070,15 @@ const _tr_flush_block = (s, buf, stored_len, last) => {
|
||||||
// opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
// opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
||||||
// s->sym_next / 3));
|
// s->sym_next / 3));
|
||||||
|
|
||||||
if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
|
if (static_lenb <= opt_lenb) {
|
||||||
|
opt_lenb = static_lenb;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Assert(buf != (char*)0, "lost buf");
|
// Assert(buf != (char*)0, "lost buf");
|
||||||
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
|
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
|
if (stored_len + 4 <= opt_lenb && buf !== -1) {
|
||||||
/* 4: two words for the lengths */
|
/* 4: two words for the lengths */
|
||||||
|
|
||||||
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
|
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
|
||||||
|
@ -1118,12 +1088,9 @@ const _tr_flush_block = (s, buf, stored_len, last) => {
|
||||||
* transform a block into a stored block.
|
* transform a block into a stored block.
|
||||||
*/
|
*/
|
||||||
_tr_stored_block(s, buf, stored_len, last);
|
_tr_stored_block(s, buf, stored_len, last);
|
||||||
|
|
||||||
} else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
|
} else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
|
||||||
|
|
||||||
send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
|
send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
|
||||||
compress_block(s, static_ltree, static_dtree);
|
compress_block(s, static_ltree, static_dtree);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
|
send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
|
||||||
send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
|
send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
|
||||||
|
@ -1140,13 +1107,13 @@ const _tr_flush_block = (s, buf, stored_len, last) => {
|
||||||
}
|
}
|
||||||
// Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
// Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
||||||
// s->compressed_len-7*last));
|
// s->compressed_len-7*last));
|
||||||
};
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Save the match info and tally the frequency counts. Return true if
|
* Save the match info and tally the frequency counts. Return true if
|
||||||
* the current block must be flushed.
|
* the current block must be flushed.
|
||||||
*/
|
*/
|
||||||
const _tr_tally = (s, dist, lc) => {
|
export function _tr_tally(s: DeflateState, dist: number, lc: number) {
|
||||||
// deflate_state *s;
|
// deflate_state *s;
|
||||||
// unsigned dist; /* distance of matched string */
|
// unsigned dist; /* distance of matched string */
|
||||||
// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||||
|
@ -1169,11 +1136,5 @@ const _tr_tally = (s, dist, lc) => {
|
||||||
s.dyn_dtree[d_code(dist) * 2] /*.Freq*/++;
|
s.dyn_dtree[d_code(dist) * 2] /*.Freq*/++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (s.sym_next === s.sym_end);
|
return s.sym_next === s.sym_end;
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports._tr_init = _tr_init;
|
|
||||||
module.exports._tr_stored_block = _tr_stored_block;
|
|
||||||
module.exports._tr_flush_block = _tr_flush_block;
|
|
||||||
module.exports._tr_tally = _tr_tally;
|
|
||||||
module.exports._tr_align = _tr_align;
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
|
import { Uint8Array } from "../utils/buffs";
|
||||||
|
import { Z_UNKNOWN } from "./constants";
|
||||||
|
|
||||||
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||||
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
|
||||||
|
@ -19,29 +22,27 @@
|
||||||
// misrepresented as being the original software.
|
// misrepresented as being the original software.
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
function ZStream() {
|
export class ZStream<State> {
|
||||||
/* next input byte */
|
/* next input byte */
|
||||||
this.input = null; // JS specific, because we have no pointers
|
public input!: Uint8Array; // JS specific, because we have no pointers
|
||||||
this.next_in = 0;
|
public next_in = 0;
|
||||||
/* number of bytes available at input */
|
/* number of bytes available at input */
|
||||||
this.avail_in = 0;
|
public avail_in = 0;
|
||||||
/* total number of input bytes read so far */
|
/* total number of input bytes read so far */
|
||||||
this.total_in = 0;
|
public total_in = 0;
|
||||||
/* next output byte should be put there */
|
/* next output byte should be put there */
|
||||||
this.output = null; // JS specific, because we have no pointers
|
public output!: Uint8Array; // JS specific, because we have no pointers
|
||||||
this.next_out = 0;
|
public next_out = 0;
|
||||||
/* remaining free space at output */
|
/* remaining free space at output */
|
||||||
this.avail_out = 0;
|
public avail_out = 0;
|
||||||
/* total number of bytes output so far */
|
/* total number of bytes output so far */
|
||||||
this.total_out = 0;
|
public total_out = 0;
|
||||||
/* last error message, NULL if no error */
|
/* last error message, NULL if no error */
|
||||||
this.msg = ''/*Z_NULL*/;
|
public msg?: string /*Z_NULL*/;
|
||||||
/* not visible by applications */
|
/* not visible by applications */
|
||||||
this.state = null;
|
public state!: State;
|
||||||
/* best guess about the data type: binary or text */
|
/* best guess about the data type: binary or text */
|
||||||
this.data_type = 2/*Z_UNKNOWN*/;
|
public data_type = Z_UNKNOWN;
|
||||||
/* adler32 value of the uncompressed data */
|
/* adler32 value of the uncompressed data */
|
||||||
this.adler = 0;
|
public adler = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ZStream;
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue